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);
        }
Example #2
0
        /// <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;
        }