private bool RequeueJobIfTimedOut(RedisConnection connection, string jobId, string queue) { var flags = connection.Redis.HashGet( _storage.GetRedisKey($"job:{jobId}"), new RedisValue[] { "Fetched", "Checked", "Ping" }); var fetched = flags[0]; var @checked = flags[1]; var ping = flags[2]; if (string.IsNullOrEmpty(fetched) && string.IsNullOrEmpty(@checked)) { // If the job does not have these flags set, then it is // in the implicit 'Fetched' state. This state has no // information about the time it was fetched. So we // can not do anything with the job in this state, because // there are two options: // 1. It is going to move to the implicit 'Fetched' state // in a short time. // 2. It will stay in the 'Fetched' state forever due to // its processing server is dead. // To ensure its server is dead, we'll move the job to // the implicit 'Checked' state with the current timestamp // and will not do anything else at this pass of the watcher. // If job's state will still be 'Checked' on the later passes // and after the CheckedTimeout expired, then the server // is dead, and we'll re-queue the job. connection.Redis.HashSet( _storage.GetRedisKey($"job:{jobId}"), "Checked", JobHelper.SerializeDateTime(DateTime.UtcNow)); // Checkpoint #1-2. The job is in the implicit 'Checked' state. // It will be re-queued after the CheckedTimeout will be expired. } else if (!AliveByPingTime(ping)) { if (TimedOutByFetchedTime(fetched) || TimedOutByCheckedTime(fetched, @checked)) { var fetchedJob = new RedisFetchedJob(_storage, connection.Redis, jobId, queue); fetchedJob.Dispose(); return(true); } } return(false); }
/// <summary> /// 如果已经超时,则重新将作业入队 /// </summary> /// <param name="connection">Redis连接</param> /// <param name="jobId">作业标识</param> /// <param name="queue">队列</param> private bool RequeueJobIfTimedOut(RedisConnection connection, string jobId, string queue) { var flags = connection.RedisClient.HMGet(_storage.GetRedisKey($"job:{jobId}"), new string[] { "Fetched", "Checked" }); var fetched = flags[0]; var @checked = flags[1]; if (string.IsNullOrEmpty(fetched) && string.IsNullOrEmpty(@checked)) { connection.RedisClient.HSet(_storage.GetRedisKey($"job:{jobId}"), "Checked", JobHelper.SerializeDateTime(DateTime.UtcNow)); } else { if (TimedOutByFetchedTime(fetched) || TimedOutByCheckedTime(fetched, @checked)) { var fetchedJob = new RedisFetchedJob(_storage, connection.RedisClient, jobId, queue); fetchedJob.Dispose(); return(true); } } return(false); }
private bool RequeueJobIfTimedOut(RedisConnection connection, string jobId, string queue) { var flags = connection.Redis.HashGet( string.Format(RedisStorage.Prefix + "job:{0}", jobId), new RedisValue[]{"Fetched","Checked"}); var fetched = flags[0]; var @checked = flags[1]; if (string.IsNullOrEmpty(fetched) && string.IsNullOrEmpty(@checked)) { // If the job does not have these flags set, then it is // in the implicit 'Fetched' state. This state has no // information about the time it was fetched. So we // can not do anything with the job in this state, because // there are two options: // 1. It is going to move to the implicit 'Fetched' state // in a short time. // 2. It will stay in the 'Fetched' state forever due to // its processing server is dead. // To ensure its server is dead, we'll move the job to // the implicit 'Checked' state with the current timestamp // and will not do anything else at this pass of the watcher. // If job's state will still be 'Checked' on the later passes // and after the CheckedTimeout expired, then the server // is dead, and we'll re-queue the job. connection.Redis.HashSet( string.Format(RedisStorage.Prefix + "job:{0}", jobId), "Checked", JobHelper.SerializeDateTime(DateTime.UtcNow)); // Checkpoint #1-2. The job is in the implicit 'Checked' state. // It will be re-queued after the CheckedTimeout will be expired. } else { if (TimedOutByFetchedTime(fetched) || TimedOutByCheckedTime(fetched, @checked)) { var fetchedJob = new RedisFetchedJob(connection.Redis, jobId, queue); fetchedJob.Dispose(); return true; } } return false; }