Example #1
0
        /// <summary>
        /// Store the given <see cref="T:Quartz.ICalendar"/>.
        /// </summary>
        /// <param name="name">The name.</param><param name="calendar">The <see cref="T:Quartz.ICalendar"/> to be stored.</param><param name="replaceExisting">If <see langword="true"/>, any <see cref="T:Quartz.ICalendar"/> existing
        ///             in the <see cref="T:Quartz.Spi.IJobStore"/> with the same name and group
        ///             should be over-written.</param><param name="updateTriggers">If <see langword="true"/>, any <see cref="T:Quartz.ITrigger"/>s existing
        ///             in the <see cref="T:Quartz.Spi.IJobStore"/> that reference an existing
        ///             Calendar with the same name with have their next fire time
        ///             re-computed with the new <see cref="T:Quartz.ICalendar"/>.</param><throws>ObjectAlreadyExistsException </throws>
        public override void StoreCalendar(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers)
        {
            string calendarHashKey = RedisJobStoreSchema.CalendarHashKey(name);

            if (replaceExisting == false && Db.KeyExists(calendarHashKey))
            {
                throw new ObjectAlreadyExistsException(string.Format("Calendar with key {0} already exists", calendarHashKey));
            }

            Db.HashSet(calendarHashKey, ConvertToHashEntries(calendar));
            Db.SetAdd(RedisJobStoreSchema.CalendarsSetKey(), calendarHashKey);

            if (updateTriggers)
            {
                var calendarTriggersSetkey = RedisJobStoreSchema.CalendarTriggersSetKey(name);

                var triggerHashKeys = Db.SetMembers(calendarTriggersSetkey);

                foreach (var triggerHashKey in triggerHashKeys)
                {
                    var trigger = RetrieveTrigger(RedisJobStoreSchema.TriggerKey(triggerHashKey));

                    trigger.UpdateWithNewCalendar(calendar, TimeSpan.FromSeconds(MisfireThreshold));

                    StoreTrigger(trigger, true);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Called by the QuartzScheduler before the <see cref="T:Quartz.Spi.IJobStore"/> is
        ///             used, in order to give the it a chance to Initialize.
        /// here we default triggerLockTime out to 5 mins (number in miliseconds)
        /// default redisLockTimeout to 5 secs (number in miliseconds)
        /// </summary>
        public Task Initialize(ITypeLoadHelper loadHelper, ISchedulerSignaler signaler, CancellationToken cancellationToken = default(CancellationToken))
        {
            _storeSchema = new RedisJobStoreSchema(KeyPrefix ?? string.Empty, KeyDelimiter ?? ":");
            _db          = ConnectionMultiplexer.Connect(RedisConfiguration).GetDatabase(0);
            _storage     = new RedisStorage(_storeSchema, _db, signaler, InstanceId, TriggerLockTimeout ?? 300000, RedisLockTimeout ?? 5000);

            return(Task.FromResult(0));
        }
Example #3
0
        /// <summary>
        /// remove the trigger from all the possible state in the its respective sorted set.
        /// </summary>
        /// <param name="triggerHashKey">trigger hash key</param>
        /// <returns>succeeds or not</returns>
        public override bool UnsetTriggerState(string triggerHashKey)
        {
            var removedList = (from RedisTriggerState state in Enum.GetValues(typeof(RedisTriggerState)) select Db.SortedSetRemove(RedisJobStoreSchema.TriggerStateSetKey(state), triggerHashKey)).ToList();

            if (removedList.Any(x => x))
            {
                return(Db.KeyDelete(
                           RedisJobStoreSchema.TriggerLockKey(RedisJobStoreSchema.TriggerKey(triggerHashKey))));
            }

            return(false);
        }
Example #4
0
        /// <summary>
        /// Remove (delete) the <see cref="T:Quartz.ITrigger"/> with the given key.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If removal of the <see cref="T:Quartz.ITrigger"/> results in an empty group, the
        ///             group should be removed from the <see cref="T:Quartz.Spi.IJobStore"/>'s list of
        ///             known group names.
        /// </para>
        /// <para>
        /// If removal of the <see cref="T:Quartz.ITrigger"/> results in an 'orphaned' <see cref="T:Quartz.IJob"/>
        ///             that is not 'durable', then the <see cref="T:Quartz.IJob"/> should be deleted
        ///             also.
        /// </para>
        /// </remarks>
        /// <returns>
        /// <see langword="true"/> if a <see cref="T:Quartz.ITrigger"/> with the given
        ///             name and group was found and removed from the store.
        /// </returns>
        public override bool RemoveTrigger(TriggerKey triggerKey, bool removeNonDurableJob = true)
        {
            var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey);

            if (!Db.KeyExists(triggerHashKey))
            {
                return(false);
            }

            IOperableTrigger trigger = RetrieveTrigger(triggerKey);

            var triggerGroupSetKey = RedisJobStoreSchema.TriggerGroupSetKey(triggerKey.Group);
            var jobHashKey         = RedisJobStoreSchema.JobHashKey(trigger.JobKey);
            var jobTriggerSetkey   = RedisJobStoreSchema.JobTriggersSetKey(trigger.JobKey);

            Db.SetRemove(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey);

            Db.SetRemove(triggerGroupSetKey, triggerHashKey);

            Db.SetRemove(jobTriggerSetkey, triggerHashKey);

            if (Db.SetLength(triggerGroupSetKey) == 0)
            {
                Db.SetRemove(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey);
            }

            if (removeNonDurableJob)
            {
                var jobTriggerSetKeyLengthResult = Db.SetLength(jobTriggerSetkey);

                var jobExistsResult = Db.KeyExists(jobHashKey);

                if (jobTriggerSetKeyLengthResult == 0 && jobExistsResult)
                {
                    var job = RetrieveJob(trigger.JobKey);

                    if (job.Durable == false)
                    {
                        RemoveJob(job.Key);
                        SchedulerSignaler.NotifySchedulerListenersJobDeleted(job.Key);
                    }
                }
            }

            if (!string.IsNullOrEmpty(trigger.CalendarName))
            {
                Db.SetRemove(RedisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName), triggerHashKey);
            }

            this.UnsetTriggerState(triggerHashKey);
            return(Db.KeyDelete(triggerHashKey));
        }
Example #5
0
        /// <summary>
        /// Remove (delete) the <see cref="T:Quartz.ICalendar"/> with the
        ///             given name.
        /// </summary>
        /// <remarks>
        /// If removal of the <see cref="T:Quartz.ICalendar"/> would result in
        ///             <see cref="T:Quartz.ITrigger"/>s pointing to non-existent calendars, then a
        ///             <see cref="T:Quartz.JobPersistenceException"/> will be thrown.
        /// </remarks>
        /// <param name="calendarName">The name of the <see cref="T:Quartz.ICalendar"/> to be removed.</param>
        /// <returns>
        /// <see langword="true"/> if a <see cref="T:Quartz.ICalendar"/> with the given name
        ///             was found and removed from the store.
        /// </returns>
        public override bool RemoveCalendar(string calendarName)
        {
            var calendarTriggersSetKey = RedisJobStoreSchema.CalendarTriggersSetKey(calendarName);

            if (Db.SetLength(calendarTriggersSetKey) > 0)
            {
                throw new JobPersistenceException(string.Format("There are triggers are using calendar {0}",
                                                                calendarName));
            }

            var calendarHashKey = RedisJobStoreSchema.CalendarHashKey(calendarName);

            return(Db.KeyDelete(calendarHashKey) && Db.SetRemove(RedisJobStoreSchema.CalendarsSetKey(), calendarHashKey));
        }
Example #6
0
        /// <summary>
        /// Remove (delete) the <see cref="T:Quartz.IJob"/> with the given
        ///             key, and any <see cref="T:Quartz.ITrigger"/> s that reference
        ///             it.
        /// </summary>
        /// <remarks>
        /// If removal of the <see cref="T:Quartz.IJob"/> results in an empty group, the
        ///             group should be removed from the <see cref="T:Quartz.Spi.IJobStore"/>'s list of
        ///             known group names.
        /// </remarks>
        /// <returns>
        /// <see langword="true"/> if a <see cref="T:Quartz.IJob"/> with the given name and
        ///             group was found and removed from the store.
        /// </returns>
        public override bool RemoveJob(JobKey jobKey)
        {
            var jobHashKey        = RedisJobStoreSchema.JobHashKey(jobKey);
            var jobDataMapHashKey = RedisJobStoreSchema.JobDataMapHashKey(jobKey);
            var jobGroupSetKey    = RedisJobStoreSchema.JobGroupSetKey(jobKey.Group);
            var jobTriggerSetKey  = RedisJobStoreSchema.JobTriggersSetKey(jobKey);

            var delJobHashKeyResult = Db.KeyDelete(jobHashKey);

            Db.KeyDelete(jobDataMapHashKey);

            Db.SetRemove(RedisJobStoreSchema.JobsSetKey(), jobHashKey);

            Db.SetRemove(jobGroupSetKey, jobHashKey);

            var jobTriggerSetResult = Db.SetMembers(jobTriggerSetKey);

            Db.KeyDelete(jobTriggerSetKey);

            var jobGroupSetLengthResult = Db.SetLength(jobGroupSetKey);

            if (jobGroupSetLengthResult == 0)
            {
                Db.SetRemoveAsync(RedisJobStoreSchema.JobGroupsSetKey(), jobGroupSetKey);
            }

            // remove all triggers associated with this job
            foreach (var triggerHashKey in jobTriggerSetResult)
            {
                var triggerkey      = RedisJobStoreSchema.TriggerKey(triggerHashKey);
                var triggerGroupKey = RedisJobStoreSchema.TriggerGroupSetKey(triggerkey.Group);

                this.UnsetTriggerState(triggerHashKey);

                Db.SetRemove(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey);

                Db.SetRemove(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupKey);

                Db.SetRemove(RedisJobStoreSchema.TriggerGroupSetKey(triggerkey.Group), triggerHashKey);

                Db.KeyDelete(triggerHashKey.ToString());
            }

            return(delJobHashKeyResult);
        }
Example #7
0
        /// <summary>
        /// Resume (un-pause) the <see cref="T:Quartz.ITrigger"/> with the
        ///             given key.
        /// <para>
        /// If the <see cref="T:Quartz.ITrigger"/> missed one or more fire-times, then the
        ///             <see cref="T:Quartz.ITrigger"/>'s misfire instruction will be applied.
        /// </para>
        /// </summary>
        /// <seealso cref="T:System.String"/>
        public override void ResumeTrigger(TriggerKey triggerKey)
        {
            var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey);

            var triggerExists = Db.SetContains(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey);

            var isPausedTrigger =
                Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused),
                                  triggerHashKey);

            var isPausedBlockedTrigger =
                Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked),
                                  triggerHashKey);

            if (triggerExists == false)
            {
                return;
            }

            //Trigger is not paused, cant be resumed then.
            if (!isPausedTrigger.HasValue && !isPausedBlockedTrigger.HasValue)
            {
                return;
            }

            var trigger = RetrieveTrigger(triggerKey);

            var jobHashKey = RedisJobStoreSchema.JobHashKey(trigger.JobKey);

            var nextFireTime = trigger.GetNextFireTimeUtc();

            if (nextFireTime.HasValue)
            {
                if (Db.SetContains(RedisJobStoreSchema.BlockedJobsSet(), jobHashKey))
                {
                    SetTriggerState(RedisTriggerState.Blocked, nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey);
                }
                else
                {
                    SetTriggerState(RedisTriggerState.Waiting, nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey);
                }
            }
            ApplyMisfire(trigger);
        }
Example #8
0
        /// <summary>
        /// Store the given <see cref="T:Quartz.IJobDetail"/>.
        /// </summary>
        /// <param name="jobDetail">The <see cref="T:Quartz.IJobDetail"/> to be stored.</param><param name="replaceExisting">If <see langword="true"/>, any <see cref="T:Quartz.IJob"/> existing in the
        ///             <see cref="T:Quartz.Spi.IJobStore"/> with the same name and group should be
        ///             over-written.
        ///             </param>
        public override void StoreJob(IJobDetail jobDetail, bool replaceExisting)
        {
            var jobHashKey        = RedisJobStoreSchema.JobHashKey(jobDetail.Key);
            var jobDataMapHashKey = RedisJobStoreSchema.JobDataMapHashKey(jobDetail.Key);
            var jobGroupSetKey    = RedisJobStoreSchema.JobGroupSetKey(jobDetail.Key.Group);

            if (Db.KeyExists(jobHashKey) && !replaceExisting)
            {
                throw new ObjectAlreadyExistsException(jobDetail);
            }

            Db.HashSet(jobHashKey, ConvertToHashEntries(jobDetail));

            Db.HashSet(jobDataMapHashKey, ConvertToHashEntries(jobDetail.JobDataMap));

            Db.SetAdd(RedisJobStoreSchema.JobsSetKey(), jobHashKey);

            Db.SetAdd(RedisJobStoreSchema.JobGroupsSetKey(), jobGroupSetKey);

            Db.SetAdd(jobGroupSetKey, jobHashKey);
        }
Example #9
0
        /// <summary>
        /// Store the given <see cref="T:Quartz.ITrigger"/>.
        /// </summary>
        /// <param name="trigger">The <see cref="T:Quartz.ITrigger"/> to be stored.</param><param name="replaceExisting">If <see langword="true"/>, any <see cref="T:Quartz.ITrigger"/> existing in
        ///             the <see cref="T:Quartz.Spi.IJobStore"/> with the same name and group should
        ///             be over-written.</param><throws>ObjectAlreadyExistsException </throws>
        public override void StoreTrigger(ITrigger trigger, bool replaceExisting)
        {
            var triggerHashKey     = RedisJobStoreSchema.TriggerHashkey(trigger.Key);
            var triggerGroupSetKey = RedisJobStoreSchema.TriggerGroupSetKey(trigger.Key.Group);
            var jobTriggerSetKey   = RedisJobStoreSchema.JobTriggersSetKey(trigger.JobKey);

            if (((trigger is ISimpleTrigger) == false) && ((trigger is ICronTrigger) == false))
            {
                throw new NotImplementedException("Unknown trigger, only SimpleTrigger and CronTrigger are supported");
            }

            var triggerExists = Db.KeyExists(triggerHashKey);

            if (triggerExists && replaceExisting == false)
            {
                throw new ObjectAlreadyExistsException(trigger);
            }


            Db.HashSet(triggerHashKey, ConvertToHashEntries(trigger));
            Db.SetAdd(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey);
            Db.SetAdd(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey);
            Db.SetAdd(triggerGroupSetKey, triggerHashKey);
            Db.SetAdd(jobTriggerSetKey, triggerHashKey);

            if (!string.IsNullOrEmpty(trigger.CalendarName))
            {
                var calendarTriggersSetKey = RedisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName);
                Db.SetAdd(calendarTriggersSetKey, triggerHashKey);
            }

            //if trigger already exists, remove it from all the possible states.
            if (triggerExists)
            {
                this.UnsetTriggerState(triggerHashKey);
            }

            //then update it with the new state in the its respectvie sorted set.
            UpdateTriggerState(trigger);
        }
Example #10
0
        /// <summary>
        /// Resume (un-pause) all of the <see cref="T:Quartz.ITrigger"/>s
        ///             in the given group.
        /// <para>
        /// If any <see cref="T:Quartz.ITrigger"/> missed one or more fire-times, then the
        ///             <see cref="T:Quartz.ITrigger"/>'s misfire instruction will be applied.
        /// </para>
        /// </summary>
        public override IList <string> ResumeTriggers(GroupMatcher <TriggerKey> matcher)
        {
            var resumedTriggerGroups = new List <string>();

            if (matcher.CompareWithOperator.Equals(StringOperator.Equality))
            {
                var triggerGroupSetKey =
                    RedisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue);

                Db.SetRemove(RedisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroupSetKey);

                var triggerHashKeysResult = Db.SetMembers(triggerGroupSetKey);

                foreach (var triggerHashKey in triggerHashKeysResult)
                {
                    var trigger = RetrieveTrigger(RedisJobStoreSchema.TriggerKey(triggerHashKey));

                    ResumeTrigger(trigger.Key);

                    if (!resumedTriggerGroups.Contains(trigger.Key.Group))
                    {
                        resumedTriggerGroups.Add(trigger.Key.Group);
                    }
                }
            }
            else
            {
                foreach (var triggerGroupSetKy in Db.SetMembersAsync(RedisJobStoreSchema.TriggerGroupsSetKey()).Result)
                {
                    if (matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.TriggerGroup(triggerGroupSetKy),
                                                             matcher.CompareToValue))
                    {
                        resumedTriggerGroups.AddRange(ResumeTriggers(GroupMatcher <TriggerKey> .GroupEquals(RedisJobStoreSchema.TriggerGroup(triggerGroupSetKy))));
                    }
                }
            }


            return(resumedTriggerGroups);
        }
Example #11
0
        /// <summary>
        /// Pause the <see cref="T:Quartz.IJob"/> with the given key - by
        ///             pausing all of its current <see cref="T:Quartz.ITrigger"/>s.
        /// </summary>
        public override IList <string> PauseJobs(GroupMatcher <JobKey> matcher)
        {
            var pausedJobGroups = new List <string>();

            if (matcher.CompareWithOperator.Equals(StringOperator.Equality))
            {
                var jobGroupSetKey = RedisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue);

                if (Db.SetAdd(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey))
                {
                    pausedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroupSetKey));

                    foreach (RedisValue val in Db.SetMembers(jobGroupSetKey))
                    {
                        PauseJob(RedisJobStoreSchema.JobKey(val));
                    }
                }
            }
            else
            {
                var jobGroupSets = Db.SetMembers(RedisJobStoreSchema.JobGroupsSetKey());

                var jobGroups = jobGroupSets.Where(jobGroupSet => matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.JobGroup(jobGroupSet), matcher.CompareToValue)).ToDictionary <RedisValue, string, RedisValue[]>(jobGroupSet => jobGroupSet, jobGroupSet => Db.SetMembers(jobGroupSet.ToString()));

                foreach (var jobGroup in jobGroups)
                {
                    if (Db.SetAdd(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroup.Key))
                    {
                        pausedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroup.Key));

                        foreach (var jobHashKey in jobGroup.Value)
                        {
                            PauseJob(RedisJobStoreSchema.JobKey(jobHashKey));
                        }
                    }
                }
            }

            return(pausedJobGroups);
        }
Example #12
0
        /// <summary>
        /// Pause the <see cref="T:Quartz.ITrigger"/> with the given key.
        /// </summary>
        public override void PauseTrigger(TriggerKey triggerKey)
        {
            var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey);

            var triggerExistsResult = Db.KeyExists(triggerHashKey);

            var completedScoreResult =
                Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Completed),
                                  triggerHashKey);

            var nextFireTimeResult = Db.HashGet(triggerHashKey, RedisJobStoreSchema.NextFireTime);

            var blockedScoreResult =
                Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked),
                                  triggerHashKey);


            if (!triggerExistsResult)
            {
                return;
            }

            if (completedScoreResult.HasValue)
            {
                return;
            }

            var nextFireTime = double.Parse(string.IsNullOrEmpty(nextFireTimeResult) ? "-1" : nextFireTimeResult.ToString());

            if (blockedScoreResult.HasValue)
            {
                SetTriggerState(RedisTriggerState.PausedBlocked, nextFireTime, triggerHashKey);
            }
            else
            {
                SetTriggerState(RedisTriggerState.Paused, nextFireTime, triggerHashKey);
            }
        }
Example #13
0
        /// <summary>
        /// Resume (un-pause) all of the <see cref="T:Quartz.IJob"/>s in
        ///             the given group.
        /// <para>
        /// If any of the <see cref="T:Quartz.IJob"/> s had <see cref="T:Quartz.ITrigger"/> s that
        ///             missed one or more fire-times, then the <see cref="T:Quartz.ITrigger"/>'s
        ///             misfire instruction will be applied.
        /// </para>
        /// </summary>
        public override global::Quartz.Collection.ISet <string> ResumeJobs(GroupMatcher <JobKey> matcher)
        {
            var resumedJobGroups = new List <string>();

            if (matcher.CompareWithOperator.Equals(StringOperator.Equality))
            {
                var jobGroupSetKey = RedisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue);

                var removedPausedResult = Db.SetRemove(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey);
                var jobsResult          = Db.SetMembers(jobGroupSetKey);


                if (removedPausedResult)
                {
                    resumedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroupSetKey));
                }

                foreach (var job in jobsResult)
                {
                    ResumeJob(RedisJobStoreSchema.JobKey(job));
                }
            }
            else
            {
                foreach (var jobGroupSetKey in Db.SetMembers(RedisJobStoreSchema.JobGroupsSetKey()))
                {
                    if (matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.JobGroup(jobGroupSetKey),
                                                             matcher.CompareToValue))
                    {
                        resumedJobGroups.AddRange(ResumeJobs(
                                                      GroupMatcher <JobKey> .GroupEquals(RedisJobStoreSchema.JobGroup(jobGroupSetKey))));
                    }
                }
            }

            return(new global::Quartz.Collection.HashSet <string>(resumedJobGroups));
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="redisJobStoreSchema">RedisJobStoreSchema</param>
 /// <param name="db">IDatabase</param>
 /// <param name="signaler">ISchedulerSignaler</param>
 /// <param name="schedulerInstanceId">SchedulerInstanceId</param>
 /// <param name="triggerLockTimeout">triggerLockTimeout</param>
 /// <param name="redisLockTimeout">redisLockTimeout</param>
 public RedisStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout)
     : base(redisJobStoreSchema, db, signaler, schedulerInstanceId, triggerLockTimeout, redisLockTimeout)
 {
 }
 /// <summary>
 /// constructor
 /// </summary>
 /// <param name="redisJobStoreSchema">RedisJobStoreSchema</param>
 /// <param name="db">IDatabase</param>
 /// <param name="signaler">ISchedulerSignaler</param>
 /// <param name="schedulerInstanceId">schedulerInstanceId</param>
 /// <param name="triggerLockTimeout">Trigger lock timeout(number in miliseconds) used in releasing the orphan triggers.</param>
 /// <param name="redisLockTimeout">Redis Lock timeout (number in miliseconds)</param>
 protected BaseJobStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout)
 {
     RedisJobStoreSchema = redisJobStoreSchema;
     Db = db;
     SchedulerSignaler = signaler;
     SchedulerInstanceId = schedulerInstanceId;
     _logger = LogManager.GetLogger(GetType());
     TriggerLockTimeout = triggerLockTimeout;
     RedisLockTimeout = redisLockTimeout;
 }
 /// <summary>
 /// initialize the job store 
 /// </summary>
 private static void InitializeJobStore()
 {
     JobStore = new RedisJobStore
     {
         RedisConfiguration = ConfigurationManager.AppSettings["RedisConfiguration"],
         KeyPrefix = KeyPrefix,
         InstanceId = "UnitTestInstanceId"
     };
     MockedSignaler = new Mock<ISchedulerSignaler>();
     MockedSignaler.Setup(x => x.NotifySchedulerListenersJobDeleted(null));
     MockedSignaler.Setup(x => x.SignalSchedulingChange(null));
     JobStore.Initialize(null, MockedSignaler.Object);
     Schema = new RedisJobStoreSchema(KeyPrefix);
     Db = ConnectionMultiplexer.Connect(JobStore.RedisConfiguration).GetDatabase();
 }
Example #17
0
 /// <summary>
 /// Called by the QuartzScheduler before the <see cref="T:Quartz.Spi.IJobStore"/> is
 ///             used, in order to give the it a chance to Initialize.
 /// here we default triggerLockTime out to 5 mins (number in miliseconds)
 /// default redisLockTimeout to 5 secs (number in miliseconds)
 /// </summary>
 public void Initialize(ITypeLoadHelper loadHelper, ISchedulerSignaler signaler)
 {
     _storeSchema = new RedisJobStoreSchema(KeyPrefix ?? string.Empty, KeyDelimiter ?? ":");
     _db          = ConnectionMultiplexer.Connect(RedisConfiguration).GetDatabase();
     _storage     = new RedisStorage(_storeSchema, _db, signaler, InstanceId, TriggerLockTimeout ?? 300000, RedisLockTimeout ?? 5000);
 }
Example #18
0
        /// <summary>
        /// Inform the <see cref="T:Quartz.Spi.IJobStore"/> that the scheduler is now firing the
        ///             given <see cref="T:Quartz.ITrigger"/> (executing its associated <see cref="T:Quartz.IJob"/>),
        ///             that it had previously acquired (reserved).
        /// </summary>
        /// <returns>
        /// May return null if all the triggers or their calendars no longer exist, or
        ///             if the trigger was not successfully put into the 'executing'
        ///             state.  Preference is to return an empty list if none of the triggers
        ///             could be fired.
        /// </returns>
        public override IList <TriggerFiredResult> TriggersFired(IList <IOperableTrigger> triggers)
        {
            var result = new List <TriggerFiredResult>();

            foreach (var trigger in triggers)
            {
                var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(trigger.Key);

                var triggerExistResult    = Db.KeyExists(triggerHashKey);
                var triggerAcquiredResult =
                    Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired),
                                      triggerHashKey);

                if (triggerExistResult == false)
                {
                    Logger.WarnFormat("Trigger {0} does not exist", triggerHashKey);
                    continue;
                }

                if (!triggerAcquiredResult.HasValue)
                {
                    Logger.WarnFormat("Trigger {0} was not acquired", triggerHashKey);
                    continue;
                }

                ICalendar calendar = null;

                string calendarname = trigger.CalendarName;
                if (!string.IsNullOrEmpty(calendarname))
                {
                    calendar = this.RetrieveCalendar(calendarname);

                    if (calendar == null)
                    {
                        continue;
                    }
                }

                var previousFireTime = trigger.GetPreviousFireTimeUtc();

                trigger.Triggered(calendar);

                var job = this.RetrieveJob(trigger.JobKey);

                var triggerFireBundle = new TriggerFiredBundle(job, trigger, calendar, false, DateTimeOffset.UtcNow,
                                                               previousFireTime, previousFireTime, trigger.GetNextFireTimeUtc());

                if (job.ConcurrentExecutionDisallowed)
                {
                    var jobHasKey        = this.RedisJobStoreSchema.JobHashKey(trigger.JobKey);
                    var jobTriggerSetKey = this.RedisJobStoreSchema.JobTriggersSetKey(job.Key);

                    foreach (var nonConcurrentTriggerHashKey in this.Db.SetMembers(jobTriggerSetKey))
                    {
                        var score =
                            this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting),
                                                   nonConcurrentTriggerHashKey);

                        if (score.HasValue)
                        {
                            this.SetTriggerState(RedisTriggerState.Blocked, score.Value, nonConcurrentTriggerHashKey);
                        }
                        else
                        {
                            score = this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused),
                                                           nonConcurrentTriggerHashKey);
                            if (score.HasValue)
                            {
                                this.SetTriggerState(RedisTriggerState.PausedBlocked, score.Value, nonConcurrentTriggerHashKey);
                            }
                        }
                    }


                    Db.SetAdd(this.RedisJobStoreSchema.JobBlockedKey(job.Key), this.SchedulerInstanceId);

                    Db.SetAdd(this.RedisJobStoreSchema.BlockedJobsSet(), jobHasKey);
                }

                //release the fired triggers
                var nextFireTimeUtc = trigger.GetNextFireTimeUtc();
                if (nextFireTimeUtc != null)
                {
                    var nextFireTime = nextFireTimeUtc.Value;
                    this.Db.HashSet(triggerHashKey, RedisJobStoreSchema.NextFireTime, nextFireTime.DateTime.ToUnixTimeMilliSeconds());
                    this.SetTriggerState(RedisTriggerState.Waiting, nextFireTime.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey);
                }

                else
                {
                    this.Db.HashSet(triggerHashKey, RedisJobStoreSchema.NextFireTime, "");
                    this.UnsetTriggerState(triggerHashKey);
                }

                result.Add(new TriggerFiredResult(triggerFireBundle));
            }

            return(result);
        }
Example #19
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="redisJobStoreSchema">RedisJobStoreSchema</param>
 /// <param name="db">IDatabase</param>
 /// <param name="signaler">ISchedulerSignaler</param>
 /// <param name="schedulerInstanceId">SchedulerInstanceId</param>
 /// <param name="triggerLockTimeout">triggerLockTimeout</param>
 /// <param name="redisLockTimeout">redisLockTimeout</param>
 public RedisStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout) : base(redisJobStoreSchema, db, signaler, schedulerInstanceId, triggerLockTimeout, redisLockTimeout)
 {
 }