From 89d137df4ef39e2ff912000d018cb187851b16a5 Mon Sep 17 00:00:00 2001 From: Honza Filipsky Date: Tue, 1 Feb 2022 11:56:43 +0100 Subject: [PATCH] Ported to Quartz.net 3 --- .../BaseJobStorage.cs | 597 ++++++------- .../DateTimeExtension.cs | 2 +- QuartzRedisJobStore.JobStore/EnumExtension.cs | 14 +- .../QuartzRedisJobStore.JobStore.csproj | 90 +- QuartzRedisJobStore.JobStore/RedisJobStore.cs | 513 ++++++----- .../RedisJobStoreSchema.cs | 143 +-- QuartzRedisJobStore.JobStore/RedisStorage.cs | 813 +++++++----------- QuartzRedisJobStore.JobStore/app.config | 67 ++ QuartzRedisJobStore.JobStore/packages.config | 28 +- QuartzRedisJobStore.UnitTest/App.config | 74 +- QuartzRedisJobStore.UnitTest/BaseFixture.cs | 65 +- .../CalendarFixture.cs | 90 +- QuartzRedisJobStore.UnitTest/JobFixture.cs | 254 +++--- .../QuartzRedisJobStore.UnitTest.csproj | 76 +- .../RedisJobStoreFixture.cs | 37 +- QuartzRedisJobStore.UnitTest/TestJobs.cs | 5 +- .../TriggerFixture.cs | 489 +++++------ .../TriggerJobCompleteFixture.cs | 70 +- QuartzRedisJobStore.UnitTest/packages.config | 23 +- 19 files changed, 1798 insertions(+), 1652 deletions(-) create mode 100644 QuartzRedisJobStore.JobStore/app.config diff --git a/QuartzRedisJobStore.JobStore/BaseJobStorage.cs b/QuartzRedisJobStore.JobStore/BaseJobStorage.cs index c03562a..a367433 100644 --- a/QuartzRedisJobStore.JobStore/BaseJobStorage.cs +++ b/QuartzRedisJobStore.JobStore/BaseJobStorage.cs @@ -9,8 +9,11 @@ using Quartz.Impl.Triggers; using Quartz.Spi; using StackExchange.Redis; -using log4net; using System.Threading; +using System.Threading.Tasks; +using System.Globalization; +using Microsoft.Extensions.Logging; +using System.Timers; namespace QuartzRedisJobStore.JobStore { @@ -22,57 +25,52 @@ public abstract class BaseJobStorage /// /// Logger /// - private readonly ILog _logger; + readonly ILogger logger; /// /// Utc datetime of Epoch. /// - private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + static readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); /// /// RedisJobStoreSchema /// - protected readonly RedisJobStoreSchema RedisJobStoreSchema; + protected readonly RedisJobStoreSchema redisJobStoreSchema; /// /// ISchedulerSignaler /// - protected readonly ISchedulerSignaler SchedulerSignaler; + protected readonly ISchedulerSignaler signaler; /// /// threshold for the misfire (measured in milliseconds) /// - protected int MisfireThreshold = 60000; + protected int misfireThreshold = 60000; /// /// redis db. /// - protected IDatabase Db; + protected IDatabase db; /// /// Triggerlock time out here we need to make sure the longest job should not exceed this amount of time, otherwise we need to increase it. /// - protected int TriggerLockTimeout; - - /// - /// lockValue - /// - protected string LockValue; + protected int triggerLockTimeout; /// /// redis lock time out in milliseconds. /// - protected int RedisLockTimeout; + protected int redisLockTimeout; /// /// scheduler instance id /// - protected readonly string SchedulerInstanceId; + protected readonly string schedulerInstanceId; /// /// JsonSerializerSettings /// - private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, DateTimeZoneHandling = DateTimeZoneHandling.Utc, NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }; + readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, DateTimeZoneHandling = DateTimeZoneHandling.Utc, NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() }; /// /// constructor @@ -83,15 +81,15 @@ public abstract class BaseJobStorage /// schedulerInstanceId /// Trigger lock timeout(number in miliseconds) used in releasing the orphan triggers. /// Redis Lock timeout (number in miliseconds) - protected BaseJobStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout) + protected BaseJobStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout, ILogger logger) { - RedisJobStoreSchema = redisJobStoreSchema; - Db = db; - SchedulerSignaler = signaler; - SchedulerInstanceId = schedulerInstanceId; - _logger = LogManager.GetLogger(GetType()); - TriggerLockTimeout = triggerLockTimeout; - RedisLockTimeout = redisLockTimeout; + this.redisJobStoreSchema = redisJobStoreSchema; + this.db = db; + this.signaler = signaler; + this.schedulerInstanceId = schedulerInstanceId; + this.logger = logger; + this.triggerLockTimeout = triggerLockTimeout; + this.redisLockTimeout = redisLockTimeout; } @@ -102,7 +100,7 @@ protected BaseJobStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, /// with the same name and group should be /// over-written. /// - public abstract void StoreJob(IJobDetail jobDetail, Boolean replaceExisting); + public abstract Task StoreJobAsync(IJobDetail jobDetail, bool replaceExisting); /// /// Retrieve the for the given @@ -111,32 +109,34 @@ protected BaseJobStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, /// /// The desired , or null if there is no match. /// - public IJobDetail RetrieveJob(JobKey jobKey) + public async Task RetrieveJobAsync(JobKey jobKey) { - var jobHashKey = RedisJobStoreSchema.JobHashKey(jobKey); - - HashEntry[] jobDetails = Db.HashGetAll(jobHashKey); + var jobHashKey = redisJobStoreSchema.JobHashKey(jobKey); + var jobDetails = await db.HashGetAllAsync(jobHashKey); - if (jobDetails == null || jobDetails.Count() == 0) - { + if (jobDetails == null || !jobDetails.Any()) return null; - } - var jobDataMapHashKey = RedisJobStoreSchema.JobDataMapHashKey(jobKey); + var jobDataMapHashKey = redisJobStoreSchema.JobDataMapHashKey(jobKey); + var jobDataMap = await db.HashGetAllAsync(jobDataMapHashKey); + var jobProperties = ConvertToDictionaryString(jobDetails); - HashEntry[] jobDataMap = Db.HashGetAll(jobDataMapHashKey); + var jobType = Type.GetType(jobProperties[RedisJobStoreSchema.JobClass]); - var jobProperties = ConvertToDictionaryString(jobDetails); + if (jobType == null) + { + logger.LogWarning("Could not find job class {0} for job {1}", jobProperties[RedisJobStoreSchema.JobClass], jobKey); + return null; + } var jobBuilder = - JobBuilder.Create(Type.GetType(jobProperties[RedisJobStoreSchema.JobClass])) + JobBuilder.Create(jobType) .WithIdentity(jobKey) .WithDescription(jobProperties[RedisJobStoreSchema.Description]) .RequestRecovery(Convert.ToBoolean(Convert.ToInt16(jobProperties[RedisJobStoreSchema.RequestRecovery]))) .StoreDurably(Convert.ToBoolean(Convert.ToInt16(jobProperties[RedisJobStoreSchema.IsDurable]))); - - if (jobDataMap != null && jobDataMap.Count() > 0) + if (jobDataMap != null && jobDataMap.Any()) { var dataMap = new JobDataMap(ConvertToDictionaryString(jobDataMap) as IDictionary); jobBuilder.SetJobData(dataMap); @@ -150,14 +150,14 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// The to be stored.If , any existing in /// the with the same name and group should /// be over-written.ObjectAlreadyExistsException - public abstract void StoreTrigger(ITrigger trigger, bool replaceExisting); + public abstract Task StoreTriggerAsync(ITrigger trigger, bool replaceExisting); /// /// remove the trigger state from all the possible sorted set. /// /// TriggerHashKey /// succeeds or not - public abstract bool UnsetTriggerState(string triggerHashKey); + public abstract Task UnsetTriggerStateAsync(string triggerHashKey); /// @@ -169,7 +169,7 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// in the that reference an existing /// Calendar with the same name with have their next fire time /// re-computed with the new .ObjectAlreadyExistsException - public abstract void StoreCalendar(String name, ICalendar calendar, bool replaceExisting, bool updateTriggers); + public abstract Task StoreCalendarAsync(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers); /// /// Remove (delete) the with the @@ -185,7 +185,7 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// if a with the given name /// was found and removed from the store. /// - public abstract bool RemoveCalendar(String calendarName); + public abstract Task RemoveCalendarAsync(string calendarName); /// /// Remove (delete) the with the given @@ -201,7 +201,7 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// if a with the given name and /// group was found and removed from the store. /// - public abstract bool RemoveJob(JobKey jobKey); + public abstract Task RemoveJobAsync(JobKey jobKey); /// /// Pause all of the s in the given @@ -213,7 +213,7 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// /// /// - public abstract IList PauseJobs(GroupMatcher matcher); + public abstract Task> PauseJobsAsync(GroupMatcher matcher); /// /// Resume (un-pause) the with the @@ -224,24 +224,20 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// instruction will be applied. /// /// - public void ResumeJob(JobKey jobKey) + public async Task ResumeJobAsync(JobKey jobKey) { - foreach (var trigger in GetTriggersForJob(jobKey)) - { - ResumeTrigger(trigger.Key); - } + foreach (var trigger in await GetTriggersForJobAsync(jobKey)) + await ResumeTriggerAsync(trigger.Key); } /// /// Pause the with the given key - by /// pausing all of its current s. /// - public void PauseJob(JobKey jobKey) + public async Task PauseJobAsync(JobKey jobKey) { - foreach (var trigger in GetTriggersForJob(jobKey)) - { - PauseTrigger(trigger.Key); - } + foreach (var trigger in await GetTriggersForJobAsync(jobKey)) + await PauseTriggerAsync(trigger.Key); } @@ -254,8 +250,7 @@ public void PauseJob(JobKey jobKey) /// misfire instruction will be applied. /// /// - public abstract global::Quartz.Collection.ISet ResumeJobs(GroupMatcher matcher); - + public abstract Task> ResumeJobsAsync(GroupMatcher matcher); /// /// Resume (un-pause) the with the @@ -266,7 +261,7 @@ public void PauseJob(JobKey jobKey) /// /// /// - public abstract void ResumeTrigger(TriggerKey triggerKey); + public abstract Task ResumeTriggerAsync(TriggerKey triggerKey); /// /// Remove (delete) the with the given key. @@ -287,7 +282,7 @@ public void PauseJob(JobKey jobKey) /// if a with the given /// name and group was found and removed from the store. /// - public abstract bool RemoveTrigger(TriggerKey triggerKey, bool removeNonDurableJob = true); + public abstract Task RemoveTriggerAsync(TriggerKey triggerKey, bool removeNonDurableJob = true); /// /// Resume (un-pause) all of the s @@ -297,12 +292,12 @@ public void PauseJob(JobKey jobKey) /// 's misfire instruction will be applied. /// /// - public abstract IList ResumeTriggers(GroupMatcher matcher); + public abstract Task> ResumeTriggersAsync(GroupMatcher matcher); /// /// Pause the with the given key. /// - public abstract void PauseTrigger(TriggerKey triggerKey); + public abstract Task PauseTriggerAsync(TriggerKey triggerKey); /// @@ -314,13 +309,11 @@ public void PauseJob(JobKey jobKey) /// /// /// - public void PauseAllTriggers() + public async Task PauseAllTriggersAsync() { - RedisValue[] triggerGroups = Db.SetMembers(RedisJobStoreSchema.TriggerGroupsSetKey()); + var triggerGroups = await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey()); foreach (var group in triggerGroups) - { - PauseTriggers(GroupMatcher.GroupEquals(RedisJobStoreSchema.TriggerGroup(group))); - } + await PauseTriggersAsync(GroupMatcher.GroupEquals(redisJobStoreSchema.TriggerGroup(group))); } /// @@ -332,13 +325,11 @@ public void PauseAllTriggers() /// /// /// - public void ResumeAllTriggers() + public async Task ResumeAllTriggersAsync() { - RedisValue[] triggerGroups = Db.SetMembers(RedisJobStoreSchema.TriggerGroupsSetKey()); + var triggerGroups = await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey()); foreach (var group in triggerGroups) - { - ResumeTriggers(GroupMatcher.GroupEquals(RedisJobStoreSchema.TriggerGroup(group))); - } + await ResumeTriggersAsync(GroupMatcher.GroupEquals(redisJobStoreSchema.TriggerGroup(group))); } /// @@ -346,21 +337,19 @@ public void ResumeAllTriggers() /// /// /// - protected void ReleaseOrphanedTriggers(RedisTriggerState currentState, RedisTriggerState newState) + protected async Task ReleaseOrphanedTriggersAsync(RedisTriggerState currentState, RedisTriggerState newState) { - SortedSetEntry[] triggers = Db.SortedSetRangeByScoreWithScores(RedisJobStoreSchema.TriggerStateSetKey(currentState), 0, -1); + var triggers = await db.SortedSetRangeByScoreWithScoresAsync(redisJobStoreSchema.TriggerStateSetKey(currentState), 0, -1); foreach (var sortedSetEntry in triggers) { - string lockedId = - Db.StringGet( - RedisJobStoreSchema.TriggerLockKey( - RedisJobStoreSchema.TriggerKey(sortedSetEntry.Element.ToString()))); + var lockedId = + await db.StringGetAsync( + redisJobStoreSchema.TriggerLockKey( + redisJobStoreSchema.TriggerKey(sortedSetEntry.Element.ToString()))); // Lock key has expired. We can safely alter the trigger's state. if (string.IsNullOrEmpty(lockedId)) - { - SetTriggerState(newState, sortedSetEntry.Score, sortedSetEntry.Element); - } + await SetTriggerStateAsync(newState, sortedSetEntry.Score, sortedSetEntry.Element); } } @@ -374,21 +363,19 @@ protected void ReleaseOrphanedTriggers(RedisTriggerState currentState, RedisTrig /// if a with the given /// name and group was found and removed from the store. /// - public bool ReplaceTrigger(TriggerKey triggerKey, IOperableTrigger newTrigger) + public async Task ReplaceTriggerAsync(TriggerKey triggerKey, IOperableTrigger newTrigger) { - var oldTrigger = RetrieveTrigger(triggerKey); + var oldTrigger = await RetrieveTriggerAsync(triggerKey); - bool found = oldTrigger != null; + var found = oldTrigger != null; if (found) { if (!oldTrigger.JobKey.Equals(newTrigger.JobKey)) - { throw new JobPersistenceException("New Trigger is not linked to the same job as the old trigger"); - } - RemoveTrigger(triggerKey, false); - StoreTrigger(newTrigger, false); + await RemoveTriggerAsync(triggerKey, false); + await StoreTriggerAsync(newTrigger, false); } return found; @@ -401,18 +388,16 @@ public bool ReplaceTrigger(TriggerKey triggerKey, IOperableTrigger newTrigger) /// The desired , or null if there is no /// match. /// - public IOperableTrigger RetrieveTrigger(TriggerKey triggerKey) + public async Task RetrieveTriggerAsync(TriggerKey triggerKey) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(triggerKey); - var properties = Db.HashGetAll(triggerHashKey); + var properties = await db.HashGetAllAsync(triggerHashKey); - if (properties != null && properties.Count() > 0) - { - return RetrieveTrigger(triggerKey, ConvertToDictionaryString(properties)); - } + if (properties != null && properties.Any()) + return CreateTriggerFromProperties(triggerKey, ConvertToDictionaryString(properties)); - _logger.WarnFormat("trigger does not exist - {0}", triggerHashKey); + logger.LogWarning("trigger does not exist - {0}", triggerHashKey); return null; } @@ -420,18 +405,17 @@ public IOperableTrigger RetrieveTrigger(TriggerKey triggerKey) /// /// Release triggers currently held by schedulers which have ceased to function e.g. crashed /// - protected void ReleaseTriggers() + protected async Task ReleaseTriggersAsync() { - double misfireTime = DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(); - if (misfireTime - GetLastTriggersReleaseTime() > TriggerLockTimeout) + var misfireTime = DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(); + if (misfireTime - await GetLastTriggersReleaseTimeAsync() > triggerLockTimeout) { // it has been more than triggerLockTimeout minutes since we last released orphaned triggers - ReleaseOrphanedTriggers(RedisTriggerState.Acquired, RedisTriggerState.Waiting); - ReleaseOrphanedTriggers(RedisTriggerState.Blocked, RedisTriggerState.Waiting); - ReleaseOrphanedTriggers(RedisTriggerState.PausedBlocked, RedisTriggerState.Paused); - SetLastTriggerReleaseTime(DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds()); + await ReleaseOrphanedTriggersAsync(RedisTriggerState.Acquired, RedisTriggerState.Waiting); + await ReleaseOrphanedTriggersAsync(RedisTriggerState.Blocked, RedisTriggerState.Waiting); + await ReleaseOrphanedTriggersAsync(RedisTriggerState.PausedBlocked, RedisTriggerState.Paused); + await SetLastTriggerReleaseTimeAsync(DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds()); } - } /// @@ -443,30 +427,26 @@ protected void ReleaseTriggers() /// milliseconds. /// /// - public IList AcquireNextTriggers(DateTimeOffset noLaterThan, int maxCount, TimeSpan timeWindow) + public async Task> AcquireNextTriggersAsync(DateTimeOffset noLaterThan, int maxCount, TimeSpan timeWindow) { - ReleaseTriggers(); - + await ReleaseTriggersAsync(); var triggers = new List(); - - bool retry = false; + var retry = false; do { - var acquiredJobHashKeysForNoConcurrentExec = new global::Quartz.Collection.HashSet(); - + retry = false; + var acquiredJobHashKeysForNoConcurrentExec = new HashSet(); var score = ToUnixTimeMilliseconds(noLaterThan.Add(timeWindow)); - var waitingStateTriggers = - Db.SortedSetRangeByScoreWithScores( - RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), 0, score, - Exclude.None, Order.Ascending, 0, maxCount); + var waitingStateTriggers = await + db.SortedSetRangeByScoreWithScoresAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), 0, score, Exclude.None, Order.Ascending, 0, maxCount); + foreach (var sortedSetEntry in waitingStateTriggers) { + var trigger = await RetrieveTriggerAsync(redisJobStoreSchema.TriggerKey(sortedSetEntry.Element)); - var trigger = RetrieveTrigger(RedisJobStoreSchema.TriggerKey(sortedSetEntry.Element)); - - if (ApplyMisfire(trigger)) + if (await ApplyMisfireAsync(trigger)) { retry = true; break; @@ -474,35 +454,33 @@ public IList AcquireNextTriggers(DateTimeOffset noLaterThan, i if (trigger.GetNextFireTimeUtc() == null) { - this.UnsetTriggerState(sortedSetEntry.Element); + await UnsetTriggerStateAsync(sortedSetEntry.Element); continue; } - var jobHashKey = RedisJobStoreSchema.JobHashKey(trigger.JobKey); + var jobHashKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); + var job = await RetrieveJobAsync(trigger.JobKey); - var job = RetrieveJob(trigger.JobKey); + if (job == null) + { + Logger.LogWarning("Could not find implementation for job {0}", trigger.JobKey); + continue; + } - if (job != null && job.ConcurrentExecutionDisallowed) + if (job?.ConcurrentExecutionDisallowed == true) { if (acquiredJobHashKeysForNoConcurrentExec.Contains(jobHashKey)) - { continue; - } + acquiredJobHashKeysForNoConcurrentExec.Add(jobHashKey); } - LockTrigger(trigger.Key); - SetTriggerState(RedisTriggerState.Acquired, - sortedSetEntry.Score, sortedSetEntry.Element); + await LockTriggerAsync(trigger.Key); + await SetTriggerStateAsync(RedisTriggerState.Acquired, sortedSetEntry.Score, sortedSetEntry.Element); triggers.Add(trigger); } - - - - } while (retry); - return triggers; } @@ -511,25 +489,18 @@ public IList AcquireNextTriggers(DateTimeOffset noLaterThan, i /// fire the given , that it had previously acquired /// (reserved). /// - public void ReleaseAcquiredTrigger(IOperableTrigger trigger) + public async Task ReleaseAcquiredTriggerAsync(IOperableTrigger trigger) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(trigger.Key); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(trigger.Key); - var score = - Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired), - triggerHashKey); + var score = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired), triggerHashKey); if (score.HasValue) { if (trigger.GetNextFireTimeUtc().HasValue) - { - SetTriggerState(RedisTriggerState.Waiting, - trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); - } + await SetTriggerStateAsync(RedisTriggerState.Waiting, trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); else - { - this.UnsetTriggerState(triggerHashKey); - } + await UnsetTriggerStateAsync(triggerHashKey); } } @@ -544,7 +515,7 @@ public void ReleaseAcquiredTrigger(IOperableTrigger trigger) /// state. Preference is to return an empty list if none of the triggers /// could be fired. /// - public abstract IList TriggersFired(IList triggers); + public abstract Task> TriggersFiredAsync(IReadOnlyCollection triggers); /// /// Inform the that the scheduler has completed the @@ -553,8 +524,7 @@ public void ReleaseAcquiredTrigger(IOperableTrigger trigger) /// in the given should be updated if the /// is stateful. /// - public abstract void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail jobDetail, - SchedulerInstruction triggerInstCode); + public abstract Task TriggeredJobCompleteAsync(IOperableTrigger trigger, IJobDetail jobDetail, SchedulerInstruction triggerInstCode); /// /// Retrieve the given . @@ -564,20 +534,17 @@ public abstract void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail j /// The desired , or null if there is no /// match. /// - public ICalendar RetrieveCalendar(string calName) + public async Task RetrieveCalendarAsync(string calName) { - var calendarHashKey = RedisJobStoreSchema.CalendarHashKey(calName); + var calendarHashKey = redisJobStoreSchema.CalendarHashKey(calName); ICalendar calendar = null; - HashEntry[] calendarPropertiesInRedis = Db.HashGetAll(calendarHashKey); - - if(calendarPropertiesInRedis != null && calendarPropertiesInRedis.Count()>0) { + var calendarPropertiesInRedis = await db.HashGetAllAsync(calendarHashKey); + if (calendarPropertiesInRedis != null && calendarPropertiesInRedis.Any()) + { var calendarProperties = ConvertToDictionaryString(calendarPropertiesInRedis); - - calendar = - JsonConvert.DeserializeObject(calendarProperties[RedisJobStoreSchema.CalendarSerialized], - _serializerSettings) as ICalendar; + calendar = JsonConvert.DeserializeObject(calendarProperties[RedisJobStoreSchema.CalendarSerialized], serializerSettings) as ICalendar; } return calendar; @@ -590,29 +557,29 @@ public ICalendar RetrieveCalendar(string calName) /// /// If there are no matches, a zero-length array should be returned. /// - public IList GetTriggersForJob(JobKey jobKey) + public async Task> GetTriggersForJobAsync(JobKey jobKey) { - var jobTriggerSetKey = RedisJobStoreSchema.JobTriggersSetKey(jobKey); - var triggerHashKeys = Db.SetMembers(jobTriggerSetKey); + var jobTriggerSetKey = redisJobStoreSchema.JobTriggersSetKey(jobKey); + var triggerHashKeys = await db.SetMembersAsync(jobTriggerSetKey); - return triggerHashKeys.Select(triggerHashKey => RetrieveTrigger(RedisJobStoreSchema.TriggerKey(triggerHashKey))).ToList(); + var result = new List(); + foreach(var triggerHashKey in triggerHashKeys) + result.Add(await RetrieveTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey))); + + return result; } /// /// Gets the paused trigger groups. /// /// - public global::Quartz.Collection.ISet GetPausedTriggerGroups() + public async Task> GetPausedTriggerGroupsAsync() { - RedisValue[] triggerGroupSetKeys = - Db.SetMembers(RedisJobStoreSchema.PausedTriggerGroupsSetKey()); - - var groups = new global::Quartz.Collection.HashSet(); + var triggerGroupSetKeys = await db.SetMembersAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey()); + var groups = new List(); foreach (var triggerGroupSetKey in triggerGroupSetKeys) - { - groups.Add(RedisJobStoreSchema.TriggerGroup(triggerGroupSetKey)); - } + groups.Add(redisJobStoreSchema.TriggerGroup(triggerGroupSetKey)); return groups; @@ -623,11 +590,9 @@ public IList GetTriggersForJob(JobKey jobKey) /// /// /// - public bool IsJobGroupPaused(string groupName) + public Task IsJobGroupPausedAsync(string groupName) { - return - Db.SetContains(RedisJobStoreSchema.PausedJobGroupsSetKey(), - RedisJobStoreSchema.JobGroupSetKey(groupName)); + return db.SetContainsAsync(redisJobStoreSchema.PausedJobGroupsSetKey(), redisJobStoreSchema.JobGroupSetKey(groupName)); } /// @@ -636,11 +601,9 @@ public bool IsJobGroupPaused(string groupName) /// /// /// - public bool IsTriggerGroupPaused(string groupName) + public Task IsTriggerGroupPausedAsync(string groupName) { - return - Db.SetContains(RedisJobStoreSchema.PausedTriggerGroupsSetKey(), - RedisJobStoreSchema.TriggerGroupSetKey(groupName)); + return db.SetContainsAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey(), redisJobStoreSchema.TriggerGroupSetKey(groupName)); } /// @@ -648,9 +611,9 @@ public bool IsTriggerGroupPaused(string groupName) /// stored in the . /// /// - public int NumberOfJobs() + public async Task NumberOfJobsAsync() { - return (int)Db.SetLength(RedisJobStoreSchema.JobsSetKey()); + return (int)await db.SetLengthAsync(redisJobStoreSchema.JobsSetKey()); } /// @@ -658,9 +621,9 @@ public int NumberOfJobs() /// stored in the . /// /// - public int NumberOfTriggers() + public async Task NumberOfTriggersAsync() { - return (int)Db.SetLength(RedisJobStoreSchema.TriggersSetKey()); + return (int)await db.SetLengthAsync(redisJobStoreSchema.TriggersSetKey()); } /// @@ -668,9 +631,9 @@ public int NumberOfTriggers() /// stored in the . /// /// - public int NumberOfCalendars() + public async Task NumberOfCalendarsAsync() { - return (int)Db.SetLength(RedisJobStoreSchema.CalendarsSetKey()); + return (int)await db.SetLengthAsync(redisJobStoreSchema.CalendarsSetKey()); } /// @@ -683,7 +646,7 @@ public int NumberOfCalendars() /// /// /// - public abstract global::Quartz.Collection.ISet JobKeys(GroupMatcher matcher); + public abstract Task> JobKeysAsync(GroupMatcher matcher); /// /// Get the names of all of the s @@ -693,7 +656,7 @@ public int NumberOfCalendars() /// zero-length array (not ). /// /// - public abstract global::Quartz.Collection.ISet TriggerKeys(GroupMatcher matcher); + public abstract Task> TriggerKeysAsync(GroupMatcher matcher); /// /// Get the names of all of the @@ -703,11 +666,10 @@ public int NumberOfCalendars() /// array (not ). /// /// - public IList JobGroupNames() + public async Task> JobGroupNamesAsync() { - RedisValue[] groupsSet = Db.SetMembers(RedisJobStoreSchema.JobGroupsSetKey()); - - return groupsSet.Select(g => RedisJobStoreSchema.JobGroup(g)).ToList(); + var groupsSet = await db.SetMembersAsync(redisJobStoreSchema.JobGroupsSetKey()); + return groupsSet.Select(g => redisJobStoreSchema.JobGroup(g)).ToList(); } /// @@ -718,11 +680,10 @@ public IList JobGroupNames() /// array (not ). /// /// - public IList TriggerGroupNames() + public async Task> TriggerGroupNamesAsync() { - RedisValue[] groupsSet = Db.SetMembers(RedisJobStoreSchema.TriggerGroupsSetKey()); - - return groupsSet.Select(g => RedisJobStoreSchema.TriggerGroup(g)).ToList(); + var groupsSet = await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey()); + return groupsSet.Select(g => redisJobStoreSchema.TriggerGroup(g)).ToList(); } /// @@ -733,18 +694,17 @@ public IList TriggerGroupNames() /// a zero-length array (not ). /// /// - public IList CalendarNames() + public async Task> CalendarNamesAsync() { - RedisValue[] calendarsSet = Db.SetMembers(RedisJobStoreSchema.CalendarsSetKey()); - - return calendarsSet.Select(g => RedisJobStoreSchema.GetCalendarName(g)).ToList(); + var calendarsSet = await db.SetMembersAsync(redisJobStoreSchema.CalendarsSetKey()); + return calendarsSet.Select(g => redisJobStoreSchema.GetCalendarName(g)).ToList(); } /// /// Get the current state of the identified . /// /// - public abstract TriggerState GetTriggerState(TriggerKey triggerKey); + public abstract Task GetTriggerStateAsync(TriggerKey triggerKey); /// /// Pause all of the s in the @@ -755,7 +715,7 @@ public IList CalendarNames() /// pause on any new triggers that are added to the group while the group is /// paused. /// - public abstract IList PauseTriggers(GroupMatcher matcher); + public abstract Task> PauseTriggersAsync(GroupMatcher matcher); /// @@ -763,50 +723,42 @@ public IList CalendarNames() /// /// IOperableTrigger /// applied or not - protected bool ApplyMisfire(IOperableTrigger trigger) + protected async Task ApplyMisfireAsync(IOperableTrigger trigger) { - double misfireTime = DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(); - double score = misfireTime; + var misfireTime = DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(); + var score = misfireTime; - if (MisfireThreshold > 0) - { - misfireTime = misfireTime - MisfireThreshold; - } + if (misfireThreshold > 0) + misfireTime = misfireTime - misfireThreshold; //if the trigger has no next fire time or exceeds the misfirethreshold or enable ignore misfirepolicy // then dont apply misfire. - DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc(); + var nextFireTime = trigger.GetNextFireTimeUtc(); - if (nextFireTime.HasValue == false || + if (!nextFireTime.HasValue || (nextFireTime.HasValue && nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds() > misfireTime) || trigger.MisfireInstruction == -1) - { return false; - } ICalendar calendar = null; if (!string.IsNullOrEmpty(trigger.CalendarName)) - { - calendar = RetrieveCalendar(trigger.CalendarName); - } + calendar = await RetrieveCalendarAsync(trigger.CalendarName); - SchedulerSignaler.NotifyTriggerListenersMisfired((IOperableTrigger)trigger.Clone()); + await signaler.NotifyTriggerListenersMisfired((IOperableTrigger)trigger.Clone()); trigger.UpdateAfterMisfire(calendar); - StoreTrigger(trigger, true); + await StoreTriggerAsync(trigger, true); if (nextFireTime.HasValue == false) { - SetTriggerState(RedisTriggerState.Completed, - score, RedisJobStoreSchema.TriggerHashkey(trigger.Key)); - SchedulerSignaler.NotifySchedulerListenersFinalized(trigger); + await SetTriggerStateAsync(RedisTriggerState.Completed, score, redisJobStoreSchema.TriggerHashkey(trigger.Key)); + await signaler.NotifySchedulerListenersFinalized(trigger); } else if (nextFireTime.Equals(trigger.GetNextFireTimeUtc())) - { return false; - } + return true; } @@ -815,9 +767,9 @@ protected bool ApplyMisfire(IOperableTrigger trigger) /// /// Jobkey /// exists or not - public bool CheckExists(JobKey jobKey) + public Task CheckExistsAsync(JobKey jobKey) { - return Db.KeyExists(RedisJobStoreSchema.JobHashKey(jobKey)); + return db.KeyExistsAsync(redisJobStoreSchema.JobHashKey(jobKey)); } @@ -826,9 +778,9 @@ public bool CheckExists(JobKey jobKey) /// /// Calendar Name /// exists or not - public bool CheckExists(string calName) + public Task CheckExistsAsync(string calName) { - return Db.KeyExists(RedisJobStoreSchema.CalendarHashKey(calName)); + return db.KeyExistsAsync(redisJobStoreSchema.CalendarHashKey(calName)); } @@ -837,36 +789,34 @@ public bool CheckExists(string calName) /// /// TriggerKey /// exists or not - public bool CheckExists(TriggerKey triggerKey) + public Task CheckExistsAsync(TriggerKey triggerKey) { - return Db.KeyExists(RedisJobStoreSchema.TriggerHashkey(triggerKey)); + return db.KeyExistsAsync(redisJobStoreSchema.TriggerHashkey(triggerKey)); } /// /// delete all scheduling data - all jobs, triggers and calendars. Scheduler.Clear() /// - public void ClearAllSchedulingData() + public async Task ClearAllSchedulingData() { - // delete triggers - foreach (string jobHashKey in - Db.SetMembers(RedisJobStoreSchema.JobsSetKey())) - { - RemoveJob(RedisJobStoreSchema.JobKey(jobHashKey)); - } + // delete jobs + foreach (string jobHashKey in await db.SetMembersAsync(redisJobStoreSchema.JobsSetKey())) + await RemoveJobAsync(redisJobStoreSchema.JobKey(jobHashKey)); - foreach (var triggerHashKey in Db.SetMembers(RedisJobStoreSchema.TriggersSetKey())) - { - RemoveTrigger(RedisJobStoreSchema.TriggerKey(triggerHashKey)); - } + // delete triggers + foreach (var triggerHashKey in await db.SetMembersAsync(redisJobStoreSchema.TriggersSetKey())) + await RemoveTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey)); - foreach (var calHashName in Db.SetMembers(RedisJobStoreSchema.CalendarsSetKey())) + // delete calendars + foreach (var calHashName in await db.SetMembersAsync(redisJobStoreSchema.CalendarsSetKey())) { - Db.KeyDelete(RedisJobStoreSchema.CalendarTriggersSetKey(RedisJobStoreSchema.GetCalendarName(calHashName))); - RemoveCalendar(RedisJobStoreSchema.GetCalendarName(calHashName)); + await db.KeyDeleteAsync(redisJobStoreSchema.CalendarTriggersSetKey(redisJobStoreSchema.GetCalendarName(calHashName))); + await RemoveCalendarAsync(redisJobStoreSchema.GetCalendarName(calHashName)); } - Db.KeyDelete(RedisJobStoreSchema.PausedTriggerGroupsSetKey()); - Db.KeyDelete(RedisJobStoreSchema.PausedJobGroupsSetKey()); + await db.KeyDeleteAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey()); + await db.KeyDeleteAsync(redisJobStoreSchema.PausedJobGroupsSetKey()); + await db.KeyDeleteAsync(redisJobStoreSchema.LastTriggerReleaseTime()); } @@ -874,24 +824,23 @@ public void ClearAllSchedulingData() /// Retrieve the last time (in milliseconds) that orphaned triggers were released /// /// time in milli seconds from epoch time - protected double GetLastTriggersReleaseTime() + protected async Task GetLastTriggersReleaseTimeAsync() { - var lastReleaseTime = Db.StringGet(RedisJobStoreSchema.LastTriggerReleaseTime()); + var lastReleaseTime = await db.StringGetAsync(redisJobStoreSchema.LastTriggerReleaseTime()); if (string.IsNullOrEmpty(lastReleaseTime)) - { return 0; - } - return double.Parse(lastReleaseTime); + + return double.Parse(lastReleaseTime, CultureInfo.InvariantCulture); } /// /// Set the last time at which orphaned triggers were released /// /// time in milli seconds from epoch time - protected void SetLastTriggerReleaseTime(double time) + protected Task SetLastTriggerReleaseTimeAsync(double time) { - Db.StringSet(RedisJobStoreSchema.LastTriggerReleaseTime(), time); + return db.StringSetAsync(redisJobStoreSchema.LastTriggerReleaseTime(), time); } /// @@ -901,10 +850,10 @@ protected void SetLastTriggerReleaseTime(double time) /// time in milli seconds from epoch time /// TriggerHashKey /// succeeds or not - protected bool SetTriggerState(RedisTriggerState state, double score, string triggerHashKey) + protected async Task SetTriggerStateAsync(RedisTriggerState state, double score, string triggerHashKey) { - this.UnsetTriggerState(triggerHashKey); - return Db.SortedSetAdd(RedisJobStoreSchema.TriggerStateSetKey(state), triggerHashKey, score); + await UnsetTriggerStateAsync(triggerHashKey); + return await db.SortedSetAddAsync(redisJobStoreSchema.TriggerStateSetKey(state), triggerHashKey, score); } /// @@ -916,9 +865,8 @@ protected HashEntry[] ConvertToHashEntries(JobDataMap jobDataMap) { var entries = new List(); if (jobDataMap != null) - { - entries.AddRange(jobDataMap.Select(entry => new HashEntry(entry.Key, entry.Value.ToString()))); - } + entries.AddRange(jobDataMap.Where(entry => entry.Value != null).Select(entry => new HashEntry(entry.Key, entry.Value.ToString()))); + return entries.ToArray(); } @@ -933,9 +881,7 @@ protected IDictionary ConvertToDictionaryString(HashEntry[] entr if (entries != null) { foreach (var entry in entries) - { stringMap.Add(entry.Name, entry.Value.ToString()); - } } return stringMap; } @@ -970,40 +916,37 @@ protected HashEntry[] ConvertToHashEntries(ITrigger trigger) { var operableTrigger = trigger as IOperableTrigger; if (operableTrigger == null) - { throw new InvalidCastException("trigger needs to be IOperable"); - } var entries = new List { - new HashEntry(RedisJobStoreSchema.JobHash, this.RedisJobStoreSchema.JobHashKey(operableTrigger.JobKey)), + new HashEntry(RedisJobStoreSchema.JobHash, redisJobStoreSchema.JobHashKey(operableTrigger.JobKey)), new HashEntry(RedisJobStoreSchema.Description, operableTrigger.Description ?? ""), new HashEntry(RedisJobStoreSchema.NextFireTime, operableTrigger.GetNextFireTimeUtc().HasValue? operableTrigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds().ToString():""), new HashEntry(RedisJobStoreSchema.PrevFireTime, operableTrigger.GetPreviousFireTimeUtc().HasValue? operableTrigger.GetPreviousFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds().ToString():""), new HashEntry(RedisJobStoreSchema.Priority, operableTrigger.Priority), - new HashEntry(RedisJobStoreSchema.StartTime,operableTrigger.StartTimeUtc.DateTime.ToUnixTimeMilliSeconds().ToString()), + new HashEntry(RedisJobStoreSchema.StartTime, operableTrigger.StartTimeUtc.DateTime.ToUnixTimeMilliSeconds().ToString()), new HashEntry(RedisJobStoreSchema.EndTime, operableTrigger.EndTimeUtc.HasValue?operableTrigger.EndTimeUtc.Value.DateTime.ToUnixTimeMilliSeconds().ToString():""), - new HashEntry(RedisJobStoreSchema.FinalFireTime,operableTrigger.FinalFireTimeUtc.HasValue?operableTrigger.FinalFireTimeUtc.Value.DateTime.ToUnixTimeMilliSeconds().ToString():""), - new HashEntry(RedisJobStoreSchema.FireInstanceId,operableTrigger.FireInstanceId??string.Empty), - new HashEntry(RedisJobStoreSchema.MisfireInstruction,operableTrigger.MisfireInstruction), - new HashEntry(RedisJobStoreSchema.CalendarName,operableTrigger.CalendarName??string.Empty) + new HashEntry(RedisJobStoreSchema.FinalFireTime, operableTrigger.FinalFireTimeUtc.HasValue?operableTrigger.FinalFireTimeUtc.Value.DateTime.ToUnixTimeMilliSeconds().ToString():""), + new HashEntry(RedisJobStoreSchema.FireInstanceId, operableTrigger.FireInstanceId ?? string.Empty), + new HashEntry(RedisJobStoreSchema.MisfireInstruction, operableTrigger.MisfireInstruction), + new HashEntry(RedisJobStoreSchema.CalendarName, operableTrigger.CalendarName ?? string.Empty) }; - if (operableTrigger is ISimpleTrigger) + if (operableTrigger is ISimpleTrigger simpleTrigger) { entries.Add(new HashEntry(RedisJobStoreSchema.TriggerType, RedisJobStoreSchema.TriggerTypeSimple)); - entries.Add(new HashEntry(RedisJobStoreSchema.RepeatCount, ((ISimpleTrigger)operableTrigger).RepeatCount)); - entries.Add(new HashEntry(RedisJobStoreSchema.RepeatInterval, ((ISimpleTrigger)operableTrigger).RepeatInterval.ToString())); - entries.Add(new HashEntry(RedisJobStoreSchema.TimesTriggered, ((ISimpleTrigger)operableTrigger).TimesTriggered)); + entries.Add(new HashEntry(RedisJobStoreSchema.RepeatCount, simpleTrigger.RepeatCount)); + entries.Add(new HashEntry(RedisJobStoreSchema.RepeatInterval, simpleTrigger.RepeatInterval.ToString())); + entries.Add(new HashEntry(RedisJobStoreSchema.TimesTriggered, simpleTrigger.TimesTriggered)); } - else if (operableTrigger is ICronTrigger) + else if (operableTrigger is ICronTrigger cronTrigger) { entries.Add(new HashEntry(RedisJobStoreSchema.TriggerType, RedisJobStoreSchema.TriggerTypeCron)); - entries.Add(new HashEntry(RedisJobStoreSchema.CronExpression, ((ICronTrigger)operableTrigger).CronExpressionString)); - entries.Add(new HashEntry(RedisJobStoreSchema.TimeZoneId, ((ICronTrigger)operableTrigger).TimeZone.Id)); + entries.Add(new HashEntry(RedisJobStoreSchema.CronExpression, cronTrigger.CronExpressionString)); + entries.Add(new HashEntry(RedisJobStoreSchema.TimeZoneId, cronTrigger.TimeZone.Id)); } - return entries.ToArray(); } @@ -1016,7 +959,7 @@ protected HashEntry[] ConvertToHashEntries(ICalendar calendar) { var entries = new List { - new HashEntry(RedisJobStoreSchema.CalendarSerialized, JsonConvert.SerializeObject(calendar,_serializerSettings)) + new HashEntry(RedisJobStoreSchema.CalendarSerialized, JsonConvert.SerializeObject(calendar, serializerSettings)) }; return entries.ToArray(); @@ -1027,12 +970,11 @@ protected HashEntry[] ConvertToHashEntries(ICalendar calendar) /// /// TriggerKey /// succeed or not - protected bool LockTrigger(TriggerKey triggerKey) + protected Task LockTriggerAsync(TriggerKey triggerKey) { - return Db.StringSet(RedisJobStoreSchema.TriggerLockKey(triggerKey), SchedulerInstanceId, TimeSpan.FromSeconds(TriggerLockTimeout)); + return db.StringSetAsync(redisJobStoreSchema.TriggerLockKey(triggerKey), schedulerInstanceId, TimeSpan.FromSeconds(triggerLockTimeout)); } - #region private methods /// @@ -1041,64 +983,44 @@ protected bool LockTrigger(TriggerKey triggerKey) /// TriggerKey /// trigger's properties /// IOperableTrigger - private IOperableTrigger RetrieveTrigger(TriggerKey triggerKey, IDictionary properties) + IOperableTrigger CreateTriggerFromProperties(TriggerKey triggerKey, IDictionary properties) { var type = properties[RedisJobStoreSchema.TriggerType]; if (string.IsNullOrEmpty(type)) - { return null; - } - if (type == RedisJobStoreSchema.TriggerTypeSimple) { var simpleTrigger = new SimpleTriggerImpl(); if (!string.IsNullOrEmpty(properties[RedisJobStoreSchema.RepeatCount])) - { simpleTrigger.RepeatCount = Convert.ToInt32(properties[RedisJobStoreSchema.RepeatCount]); - } - if (!string.IsNullOrEmpty(properties[RedisJobStoreSchema.RepeatInterval])) - { simpleTrigger.RepeatInterval = TimeSpan.Parse(properties[RedisJobStoreSchema.RepeatInterval]); - } if (!string.IsNullOrEmpty(properties[RedisJobStoreSchema.TimesTriggered])) - { simpleTrigger.TimesTriggered = Convert.ToInt32(properties[RedisJobStoreSchema.TimesTriggered]); - } PopulateTrigger(triggerKey, properties, simpleTrigger); return simpleTrigger; - } else { - var cronTrigger = new CronTriggerImpl(); if (!string.IsNullOrEmpty(properties[RedisJobStoreSchema.TimeZoneId])) - { - cronTrigger.TimeZone = - TimeZoneInfo.FindSystemTimeZoneById(properties[RedisJobStoreSchema.TimeZoneId]); - } + cronTrigger.TimeZone = TimeZoneInfo.FindSystemTimeZoneById(properties[RedisJobStoreSchema.TimeZoneId]); + if (!string.IsNullOrEmpty(properties[RedisJobStoreSchema.CronExpression])) - { cronTrigger.CronExpressionString = properties[RedisJobStoreSchema.CronExpression]; - } - PopulateTrigger(triggerKey, properties, cronTrigger); return cronTrigger; - } - - } /// @@ -1107,40 +1029,36 @@ private IOperableTrigger RetrieveTrigger(TriggerKey triggerKey, IDictionarytriggerKey /// trigger's properties /// IOperableTrigger - private void PopulateTrigger(TriggerKey triggerKey, IDictionary properties, IOperableTrigger trigger) + void PopulateTrigger(TriggerKey triggerKey, IDictionary properties, IOperableTrigger trigger) { trigger.Key = triggerKey; - var jobGroupName = RedisJobStoreSchema.Split(properties[RedisJobStoreSchema.JobHash]); - trigger.JobKey = new JobKey(jobGroupName[2], jobGroupName[1]); + var (name, group) = redisJobStoreSchema.Split(properties[RedisJobStoreSchema.JobHash]); + trigger.JobKey = new JobKey(name, group); trigger.Description = properties[RedisJobStoreSchema.Description]; trigger.FireInstanceId = properties[RedisJobStoreSchema.FireInstanceId]; trigger.CalendarName = properties[RedisJobStoreSchema.CalendarName]; trigger.Priority = int.Parse(properties[RedisJobStoreSchema.Priority]); trigger.MisfireInstruction = int.Parse(properties[RedisJobStoreSchema.MisfireInstruction]); - trigger.StartTimeUtc = DateTimeFromUnixTimestampMillis( - double.Parse(properties[RedisJobStoreSchema.StartTime])); + trigger.StartTimeUtc = DateTimeFromUnixTimestampMillis(double.Parse(properties[RedisJobStoreSchema.StartTime])); trigger.EndTimeUtc = string.IsNullOrEmpty(properties[RedisJobStoreSchema.EndTime]) ? default(DateTimeOffset?) - : DateTimeFromUnixTimestampMillis( - double.Parse(properties[RedisJobStoreSchema.EndTime])); - - var baseTrigger = trigger as AbstractTrigger; + : DateTimeFromUnixTimestampMillis(double.Parse(properties[RedisJobStoreSchema.EndTime])); - if (baseTrigger != null) + if (trigger is AbstractTrigger) { - trigger.SetNextFireTimeUtc(string.IsNullOrEmpty(properties[RedisJobStoreSchema.NextFireTime]) - ? default(DateTimeOffset?) - : DateTimeFromUnixTimestampMillis( - double.Parse(properties[RedisJobStoreSchema.NextFireTime]))); - - trigger.SetPreviousFireTimeUtc(string.IsNullOrEmpty(properties[RedisJobStoreSchema.PrevFireTime]) - ? default(DateTimeOffset?) - : DateTimeFromUnixTimestampMillis( - double.Parse(properties[RedisJobStoreSchema.PrevFireTime]))); + trigger.SetNextFireTimeUtc( + string.IsNullOrEmpty(properties[RedisJobStoreSchema.NextFireTime]) + ? default(DateTimeOffset?) + : DateTimeFromUnixTimestampMillis(double.Parse(properties[RedisJobStoreSchema.NextFireTime])) + ); + + trigger.SetPreviousFireTimeUtc( + string.IsNullOrEmpty(properties[RedisJobStoreSchema.PrevFireTime]) + ? default(DateTimeOffset?) + : DateTimeFromUnixTimestampMillis(double.Parse(properties[RedisJobStoreSchema.PrevFireTime])) + ); } - - } /// @@ -1148,9 +1066,9 @@ private void PopulateTrigger(TriggerKey triggerKey, IDictionary /// /// milliseconds /// datetime in utc - private static DateTime DateTimeFromUnixTimestampMillis(double millis) + static DateTime DateTimeFromUnixTimestampMillis(double millis) { - return UnixEpoch.AddMilliseconds(millis); + return unixEpoch.AddMilliseconds(millis); } /// @@ -1162,44 +1080,41 @@ public double ToUnixTimeMilliseconds(DateTimeOffset dateTimeOffset) { // Truncate sub-millisecond precision before offsetting by the Unix Epoch to avoid // the last digit being off by one for dates that result in negative Unix times - return (dateTimeOffset - new DateTimeOffset(UnixEpoch)).TotalMilliseconds; + return (dateTimeOffset - new DateTimeOffset(unixEpoch)).TotalMilliseconds; } /// /// try to acquire a redis lock. /// /// locked or not - private bool Lock() + async Task<(bool locked, string lockValue)> TryLockAsync(CancellationToken cancellationToken) { var guid = Guid.NewGuid().ToString(); - - var lockacquired = Db.LockTake(RedisJobStoreSchema.LockKey, guid, TimeSpan.FromMilliseconds(RedisLockTimeout)); - if (lockacquired) - { - LockValue = guid; - } - return lockacquired; + var lockacquired = await db.LockTakeAsync(redisJobStoreSchema.LockKey, guid, TimeSpan.FromMilliseconds(redisLockTimeout)); + cancellationToken.ThrowIfCancellationRequested(); + return (lockacquired, lockacquired ? guid : null); } /// /// try to acquire a lock with retry /// if acquire fails, then retry till it succeeds. /// - public void LockWithWait() + public async Task LockWithWait(CancellationToken cancellationToken) { - while (!Lock()) + (bool locked, string lockValue) tuple; + while (!(tuple = await TryLockAsync(cancellationToken)).locked) { try { - _logger.Info("waiting for redis lock"); - Thread.Sleep(RandomInt(75, 125)); + logger.LogInformation("waiting for redis lock"); + await Task.Delay(RandomInt(75, 125)); } catch (ThreadInterruptedException ex) { - _logger.ErrorFormat("errored out on waiting for a lock", ex); + logger.LogError(ex, "errored out on waiting for a lock"); } } - + return tuple.lockValue; } /// @@ -1217,22 +1132,18 @@ protected int RandomInt(int min, int max) /// release the redis lock. /// /// unlock succeeds or not - public bool Unlock() + public Task UnlockAsync(string lockValue) { - var key = RedisJobStoreSchema.LockKey; - - return Db.LockRelease(key, LockValue); + return db.LockReleaseAsync(redisJobStoreSchema.LockKey, lockValue); } /// /// return the logger for the current class /// - protected ILog Logger + protected ILogger Logger { - get { return _logger; } + get { return logger; } } - #endregion - } } diff --git a/QuartzRedisJobStore.JobStore/DateTimeExtension.cs b/QuartzRedisJobStore.JobStore/DateTimeExtension.cs index 86ec67b..e8b2f96 100644 --- a/QuartzRedisJobStore.JobStore/DateTimeExtension.cs +++ b/QuartzRedisJobStore.JobStore/DateTimeExtension.cs @@ -14,7 +14,7 @@ public static class DateTimeExtension /// public static double ToUnixTimeMilliSeconds(this DateTime date) { - TimeSpan span = date - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + var span = date - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); return span.TotalMilliseconds; } } diff --git a/QuartzRedisJobStore.JobStore/EnumExtension.cs b/QuartzRedisJobStore.JobStore/EnumExtension.cs index a22ef7c..a89e84c 100644 --- a/QuartzRedisJobStore.JobStore/EnumExtension.cs +++ b/QuartzRedisJobStore.JobStore/EnumExtension.cs @@ -9,16 +9,12 @@ public static class EnumExtension { public static string GetDisplayName(this Enum enumValue) { - var att = enumValue.GetType() - .GetMember(enumValue.ToString()) - .First() - .GetCustomAttribute(); + var att = enumValue.GetType(). + GetMember(enumValue.ToString()). + First(). + GetCustomAttribute(); - if (att != null) - { - return att.Name; - } - return string.Empty; + return att?.Name ?? string.Empty; } } } diff --git a/QuartzRedisJobStore.JobStore/QuartzRedisJobStore.JobStore.csproj b/QuartzRedisJobStore.JobStore/QuartzRedisJobStore.JobStore.csproj index 29d166c..809a399 100644 --- a/QuartzRedisJobStore.JobStore/QuartzRedisJobStore.JobStore.csproj +++ b/QuartzRedisJobStore.JobStore/QuartzRedisJobStore.JobStore.csproj @@ -9,8 +9,12 @@ Properties QuartzRedisJobStore.JobStore QuartzRedisJobStore.JobStore - v4.5.2 + v4.6.1 + 8.0 512 + + + true @@ -38,25 +42,84 @@ ..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll True - - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - True + + ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Microsoft.Extensions.DependencyInjection.5.0.2\lib\net461\Microsoft.Extensions.DependencyInjection.dll - - ..\packages\Quartz.2.3.3\lib\net40\Quartz.dll - True + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll - - ..\packages\StackExchange.Redis.1.0.481\lib\net45\StackExchange.Redis.dll - True + + ..\packages\Microsoft.Extensions.Logging.5.0.0\lib\net461\Microsoft.Extensions.Logging.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Options.5.0.0\lib\net461\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Primitives.5.0.1\lib\net461\Microsoft.Extensions.Primitives.dll + + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Pipelines.Sockets.Unofficial.2.2.0\lib\net461\Pipelines.Sockets.Unofficial.dll + + + ..\packages\Quartz.3.2.3\lib\net461\Quartz.dll + + + ..\packages\Quartz.Serialization.Json.3.2.3\lib\net461\Quartz.Serialization.Json.dll + + + ..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Diagnostics.PerformanceCounter.5.0.0\lib\net461\System.Diagnostics.PerformanceCounter.dll + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + + + ..\packages\System.IO.Pipelines.5.0.0\lib\net461\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + + + + ..\packages\System.Threading.Channels.5.0.0\lib\net461\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + @@ -75,6 +138,7 @@ + diff --git a/QuartzRedisJobStore.JobStore/RedisJobStore.cs b/QuartzRedisJobStore.JobStore/RedisJobStore.cs index 62eda5a..9070eec 100644 --- a/QuartzRedisJobStore.JobStore/RedisJobStore.cs +++ b/QuartzRedisJobStore.JobStore/RedisJobStore.cs @@ -4,80 +4,106 @@ using Quartz.Impl.Matchers; using Quartz.Spi; using StackExchange.Redis; -using log4net; +using System.Threading.Tasks; +using System.Threading; +using Microsoft.Extensions.Logging; +using Quartz.Util; namespace QuartzRedisJobStore.JobStore { /// /// Redis Job Store /// - public class RedisJobStore : IJobStore + public class RedisJobStore : IJobStore, IDisposable { #region private fields /// /// logger /// - private readonly ILog _logger = LogManager.GetLogger(typeof(RedisJobStore)); + ILogger logger = NullLogger.Instance; /// /// redis job store schema /// - private RedisJobStoreSchema _storeSchema; + RedisJobStoreSchema storeSchema; + /// /// redis db. /// - private IDatabase _db; + IDatabase db; /// /// master/slave redis store. /// - private RedisStorage _storage; - + RedisStorage storage; #endregion #region public properties - /// /// Indicates whether job store supports persistence. /// /// - public bool SupportsPersistence - { - get { return true; } - } + public bool SupportsPersistence => true; + /// - /// How long (in milliseconds) the implementation - /// estimates that it will take to release a trigger and acquire a new one. + /// How long (in milliseconds) the implementation estimates that it will take to release a trigger and acquire a new one. /// - public long EstimatedTimeToReleaseAndAcquireTrigger - { - get { return 200; } - } + public long EstimatedTimeToReleaseAndAcquireTrigger => 200; + /// /// Whether or not the implementation is clustered. /// /// - public bool Clustered - { - get { return true; } - } + public bool Clustered => true; + /// - /// Inform the of the Scheduler instance's Id, - /// prior to initialize being invoked. + /// Inform the of the Scheduler instance's Id, prior to initialize being invoked. /// public string InstanceId { get; set; } + /// - /// Inform the of the Scheduler instance's name, - /// prior to initialize being invoked. + /// Inform the of the Scheduler instance's name, prior to initialize being invoked. /// public string InstanceName { get; set; } + /// /// Tells the JobStore the pool size used to execute jobs. /// public int ThreadPoolSize { get; set; } + + /// + /// Redis Configuration - either fill this as a one string (redis://{Password}@{Host}:{Port}?ssl={Ssl}&db={Database}) + /// + public string RedisConfiguration { get; set; } + + /// + /// Type of some configured or + /// + public string LoggerFactoryType { get; set; } + + /// + /// Redis configuration - Host + /// + public string Host { get; set; } + + /// + /// Redis configuration - Port + /// + public int Port { get; set; } + + /// + /// Redis configuration - Port + /// + public int Database { get; set; } + + /// + /// Redis configuration - Password + /// + public string Password { get; set; } + /// - /// Redis configuration + /// Redis configuration - SSL /// - public string RedisConfiguration { set; get; } + public bool Ssl { get; set; } /// /// gets / sets the delimiter for concatinate redis keys. @@ -108,38 +134,67 @@ public bool Clustered /// here we default triggerLockTime out to 5 mins (number in miliseconds) /// default redisLockTimeout to 5 secs (number in miliseconds) /// - public void Initialize(ITypeLoadHelper loadHelper, ISchedulerSignaler signaler) + public async Task Initialize(ITypeLoadHelper loadHelper, ISchedulerSignaler signaler, CancellationToken cancellationToken = default) { - _storeSchema = new RedisJobStoreSchema(KeyPrefix ?? string.Empty, KeyDelimiter ?? ":"); - _db = ConnectionMultiplexer.Connect(RedisConfiguration).GetDatabase(); - _storage = new RedisStorage(_storeSchema, _db, signaler, InstanceId, TriggerLockTimeout ?? 300000, RedisLockTimeout ?? 5000); + storeSchema = new RedisJobStoreSchema(KeyPrefix ?? string.Empty, KeyDelimiter ?? ":"); + + if (!string.IsNullOrEmpty(LoggerFactoryType)) + { + try + { + using var factoryOrProvider = ObjectUtils.InstantiateType(loadHelper.LoadType(LoggerFactoryType)); + if (factoryOrProvider is ILoggerFactory factory) + logger = factory.CreateLogger(); + else if (factoryOrProvider is ILoggerProvider provider) + logger = provider.CreateLogger(nameof(RedisJobStore)); + } + catch + { + } + } + + ConfigurationOptions options; + + if (!string.IsNullOrEmpty(RedisConfiguration)) + options = ConfigurationOptions.Parse(RedisConfiguration); + else + { + options = ConfigurationOptions.Parse($"{Host}:{Port}"); + options.Ssl = Ssl; + options.Password = Password; + } + db = (await ConnectionMultiplexer.ConnectAsync(options)).GetDatabase(Database); + storage = new RedisStorage(storeSchema, db, signaler, InstanceId, TriggerLockTimeout ?? 300000, RedisLockTimeout ?? 5000, logger); } /// /// Called by the QuartzScheduler to inform the that /// the scheduler has started. /// - public void SchedulerStarted() + public Task SchedulerStarted(CancellationToken cancellationToken = default) { - _logger.Info("scheduler has started"); + logger.LogInformation("scheduler has started"); + return Task.CompletedTask; } /// /// Called by the QuartzScheduler to inform the JobStore that /// the scheduler has been paused. /// - public void SchedulerPaused() + public Task SchedulerPaused(CancellationToken cancellationToken = default) { - _logger.Info("scheduler has paused"); + logger.LogInformation("scheduler has paused"); + return Task.CompletedTask; } /// /// Called by the QuartzScheduler to inform the JobStore that /// the scheduler has resumed after being paused. /// - public void SchedulerResumed() + public Task SchedulerResumed(CancellationToken cancellationToken = default) { - _logger.Info("scheduler has resumed"); + logger.LogInformation("scheduler has resumed"); + return Task.CompletedTask; } /// @@ -147,25 +202,26 @@ public void SchedulerResumed() /// it should free up all of it's resources because the scheduler is /// shutting down. /// - public void Shutdown() + public Task Shutdown(CancellationToken cancellationToken = default) { - _logger.Info("scheduler has shutdown"); - _db.Multiplexer.Dispose(); + logger.LogInformation("scheduler has shutdown"); + db?.Multiplexer.Dispose(); + db = null; + return Task.CompletedTask; } /// /// Store the given and . /// /// The to be stored.The to be stored.ObjectAlreadyExistsException - public void StoreJobAndTrigger(IJobDetail newJob, IOperableTrigger newTrigger) + public Task StoreJobAndTrigger(IJobDetail newJob, IOperableTrigger newTrigger, CancellationToken cancellationToken = default) { - _logger.Info("StoreJobAndTrigger"); - DoWithLock(() => + logger.LogInformation("StoreJobAndTrigger"); + return DoWithLock(async () => { - _storage.StoreJob(newJob, false); - _storage.StoreTrigger(newTrigger, false); - }, "Could store job/trigger"); - + await storage.StoreJobAsync(newJob, false); + await storage.StoreTriggerAsync(newTrigger, false); + }, "Could store job/trigger", cancellationToken); } /// @@ -173,11 +229,10 @@ public void StoreJobAndTrigger(IJobDetail newJob, IOperableTrigger newTrigger) /// /// /// - public bool IsJobGroupPaused(string groupName) + public Task IsJobGroupPaused(string groupName, CancellationToken cancellationToken = default) { - _logger.Info("IsJobGroupPaused"); - return DoWithLock(() => _storage.IsJobGroupPaused(groupName), - string.Format("Error on IsJobGroupPaused - Group {0}", groupName)); + logger.LogInformation("IsJobGroupPaused"); + return DoWithLock(() => storage.IsJobGroupPausedAsync(groupName), string.Format("Error on IsJobGroupPaused - Group {0}", groupName), cancellationToken); } /// @@ -186,24 +241,22 @@ public bool IsJobGroupPaused(string groupName) /// /// /// - public bool IsTriggerGroupPaused(string groupName) + public Task IsTriggerGroupPaused(string groupName, CancellationToken cancellationToken = default) { - _logger.Info("IsTriggerGroupPaused"); - return DoWithLock(() => _storage.IsTriggerGroupPaused(groupName), - string.Format("Error on IsTriggerGroupPaused - Group {0}", groupName)); + logger.LogInformation("IsTriggerGroupPaused"); + return DoWithLock(() => storage.IsTriggerGroupPausedAsync(groupName), string.Format("Error on IsTriggerGroupPaused - Group {0}", groupName), cancellationToken); } /// /// Store the given . /// /// The to be stored.If , any existing in the - /// with the same name and group should be - /// over-written. + /// with the same name and group should be over-written. /// - public void StoreJob(IJobDetail newJob, bool replaceExisting) + public Task StoreJob(IJobDetail newJob, bool replaceExisting, CancellationToken cancellationToken = default) { - _logger.Info("StoreJob"); - DoWithLock(() => _storage.StoreJob(newJob, replaceExisting), "Could not store job"); + logger.LogInformation("StoreJob"); + return DoWithLock(() => storage.StoreJobAsync(newJob, replaceExisting), "Could not store job", cancellationToken); } /// @@ -211,20 +264,17 @@ public void StoreJob(IJobDetail newJob, bool replaceExisting) /// /// jobs and triggers indexed by job /// indicate to repalce the existing ones or not - public void StoreJobsAndTriggers(IDictionary> triggersAndJobs, bool replace) + public async Task StoreJobsAndTriggers(IReadOnlyDictionary> triggersAndJobs, bool replace, CancellationToken cancellationToken = default) { - _logger.Info("StoreJobsAndTriggers"); + logger.LogInformation("StoreJobsAndTriggers"); foreach (var job in triggersAndJobs) { - DoWithLock(() => + await DoWithLock(async () => { - _storage.StoreJob(job.Key, replace); + await storage.StoreJobAsync(job.Key, replace); foreach (var trigger in job.Value) - { - _storage.StoreTrigger(trigger, replace); - } - - }, "Could store job/trigger"); + await storage.StoreTriggerAsync(trigger, replace); + }, "Could store job/trigger", cancellationToken); } } @@ -243,11 +293,10 @@ public void StoreJobsAndTriggers(IDictionary if a with the given name and /// group was found and removed from the store. /// - public bool RemoveJob(JobKey jobKey) + public Task RemoveJob(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("RemoveJob"); - return DoWithLock(() => _storage.RemoveJob(jobKey), - "Could not remove a job"); + logger.LogInformation("RemoveJob"); + return DoWithLock(() => storage.RemoveJobAsync(jobKey), "Could not remove a job", cancellationToken); } /// @@ -255,17 +304,17 @@ public bool RemoveJob(JobKey jobKey) /// /// JobKeys /// succeeds or not - public bool RemoveJobs(IList jobKeys) + public async Task RemoveJobs(IReadOnlyCollection jobKeys, CancellationToken cancellationToken = default) { - _logger.Info("RemoveJobs"); - bool removed = jobKeys.Count > 0; + logger.LogInformation("RemoveJobs"); + var removed = false; foreach (var jobKey in jobKeys) { - DoWithLock(() => + await DoWithLock(async () => { - removed = _storage.RemoveJob(jobKey); - }, "Error on removing job"); + removed |= await storage.RemoveJobAsync(jobKey); + }, "Error on removing job", cancellationToken); } return removed; @@ -278,11 +327,10 @@ public bool RemoveJobs(IList jobKeys) /// /// The desired , or null if there is no match. /// - public IJobDetail RetrieveJob(JobKey jobKey) + public Task RetrieveJob(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("RetrieveJob"); - return DoWithLock(() => _storage.RetrieveJob(jobKey), - "Could not retriev job"); + logger.LogInformation("RetrieveJob"); + return DoWithLock(() => storage.RetrieveJobAsync(jobKey), "Could not retrieve job", cancellationToken); } /// @@ -291,11 +339,10 @@ public IJobDetail RetrieveJob(JobKey jobKey) /// The to be stored.If , any existing in /// the with the same name and group should /// be over-written.ObjectAlreadyExistsException - public void StoreTrigger(IOperableTrigger newTrigger, bool replaceExisting) + public Task StoreTrigger(IOperableTrigger newTrigger, bool replaceExisting, CancellationToken cancellationToken = default) { - _logger.Info("StoreTrigger"); - DoWithLock(() => _storage.StoreTrigger(newTrigger, replaceExisting), - "Could not store trigger"); + logger.LogInformation("StoreTrigger"); + return DoWithLock(() => storage.StoreTriggerAsync(newTrigger, replaceExisting), "Could not store trigger", cancellationToken); } /// @@ -317,11 +364,10 @@ public void StoreTrigger(IOperableTrigger newTrigger, bool replaceExisting) /// if a with the given /// name and group was found and removed from the store. /// - public bool RemoveTrigger(TriggerKey triggerKey) + public Task RemoveTrigger(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("RemoveTrigger"); - return DoWithLock(() => _storage.RemoveTrigger(triggerKey), - "Could not remove trigger"); + logger.LogInformation("RemoveTrigger"); + return DoWithLock(() => storage.RemoveTriggerAsync(triggerKey), "Could not remove trigger", cancellationToken); } /// @@ -329,19 +375,17 @@ public bool RemoveTrigger(TriggerKey triggerKey) /// /// Trigger Keys /// succeeds or not - public bool RemoveTriggers(IList triggerKeys) + public async Task RemoveTriggers(IReadOnlyCollection triggerKeys, CancellationToken cancellationToken = default) { - _logger.Info("RemoveTriggers"); - - bool removed = triggerKeys.Count > 0; + logger.LogInformation("RemoveTriggers"); + var removed = false; foreach (var triggerKey in triggerKeys) { - DoWithLock(() => + await DoWithLock(async () => { - removed = _storage.RemoveTrigger(triggerKey); - }, "Error on removing trigger"); - + removed |= await storage.RemoveTriggerAsync(triggerKey); + }, "Error on removing trigger", cancellationToken); } return removed; } @@ -356,12 +400,10 @@ public bool RemoveTriggers(IList triggerKeys) /// if a with the given /// name and group was found and removed from the store. /// - public bool ReplaceTrigger(TriggerKey triggerKey, IOperableTrigger newTrigger) + public Task ReplaceTrigger(TriggerKey triggerKey, IOperableTrigger newTrigger, CancellationToken cancellationToken = default) { - _logger.Info("ReplaceTrigger"); - - return DoWithLock(() => _storage.ReplaceTrigger(triggerKey, newTrigger), - "Error on replacing trigger"); + logger.LogInformation("ReplaceTrigger"); + return DoWithLock(() => storage.ReplaceTriggerAsync(triggerKey, newTrigger), "Error on replacing trigger", cancellationToken); } /// @@ -371,12 +413,10 @@ public bool ReplaceTrigger(TriggerKey triggerKey, IOperableTrigger newTrigger) /// The desired , or null if there is no /// match. /// - public IOperableTrigger RetrieveTrigger(TriggerKey triggerKey) + public Task RetrieveTrigger(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("RetrieveTrigger"); - - return DoWithLock(() => _storage.RetrieveTrigger(triggerKey), - "could not retrieve trigger"); + logger.LogInformation("RetrieveTrigger"); + return DoWithLock(() => storage.RetrieveTriggerAsync(triggerKey), "could not retrieve trigger", cancellationToken); } /// @@ -388,12 +428,10 @@ public IOperableTrigger RetrieveTrigger(TriggerKey triggerKey) /// /// true if a calendar exists with the given identifier /// - public bool CalendarExists(string calName) + public Task CalendarExists(string calName, CancellationToken cancellationToken = default) { - _logger.Info("CalendarExists"); - - return DoWithLock(() => _storage.CheckExists(calName), - string.Format("could not check if the calendar {0} exists", calName)); + logger.LogInformation("CalendarExists"); + return DoWithLock(() => storage.CheckExistsAsync(calName), string.Format("could not check if the calendar {0} exists", calName), cancellationToken); } /// @@ -405,11 +443,10 @@ public bool CalendarExists(string calName) /// /// true if a job exists with the given identifier /// - public bool CheckExists(JobKey jobKey) + public Task CheckExists(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("CheckExists - Job"); - return DoWithLock(() => _storage.CheckExists(jobKey), - string.Format("could not check if the job {0} exists", jobKey)); + logger.LogInformation("CheckExists - Job"); + return DoWithLock(() => storage.CheckExistsAsync(jobKey), string.Format("could not check if the job {0} exists", jobKey), cancellationToken); } /// @@ -421,11 +458,10 @@ public bool CheckExists(JobKey jobKey) /// /// true if a trigger exists with the given identifier /// - public bool CheckExists(TriggerKey triggerKey) + public Task CheckExists(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("CheckExists - Trigger"); - return DoWithLock(() => _storage.CheckExists(triggerKey), - string.Format("could not check if the trigger {0} exists", triggerKey)); + logger.LogInformation("CheckExists - Trigger"); + return DoWithLock(() => storage.CheckExistsAsync(triggerKey), string.Format("could not check if the trigger {0} exists", triggerKey), cancellationToken); } /// @@ -433,10 +469,10 @@ public bool CheckExists(TriggerKey triggerKey) /// s. /// /// - public void ClearAllSchedulingData() + public Task ClearAllSchedulingData(CancellationToken cancellationToken = default) { - _logger.Info("ClearAllSchedulingData"); - DoWithLock(() => _storage.ClearAllSchedulingData(), "Could not clear all the scheduling data"); + logger.LogInformation("ClearAllSchedulingData"); + return DoWithLock(() => storage.ClearAllSchedulingData(), "Could not clear all the scheduling data", cancellationToken); } /// @@ -448,11 +484,10 @@ public void ClearAllSchedulingData() /// in the that reference an existing /// Calendar with the same name with have their next fire time /// re-computed with the new .ObjectAlreadyExistsException - public void StoreCalendar(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers) + public Task StoreCalendar(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers, CancellationToken cancellationToken = default) { - _logger.Info("StoreCalendar"); - DoWithLock(() => _storage.StoreCalendar(name, calendar, replaceExisting, updateTriggers), - string.Format("Error on store calendar - {0}", name)); + logger.LogInformation("StoreCalendar"); + return DoWithLock(() => storage.StoreCalendarAsync(name, calendar, replaceExisting, updateTriggers), string.Format("Error on store calendar - {0}", name), cancellationToken); } /// @@ -469,11 +504,10 @@ public void StoreCalendar(string name, ICalendar calendar, bool replaceExisting, /// if a with the given name /// was found and removed from the store. /// - public bool RemoveCalendar(string calName) + public Task RemoveCalendar(string calName, CancellationToken cancellationToken = default) { - _logger.Info("RemoveCalendar"); - return DoWithLock(() => _storage.RemoveCalendar(calName), - string.Format("Error on remvoing calendar - {0}", calName)); + logger.LogInformation("RemoveCalendar"); + return DoWithLock(() => storage.RemoveCalendarAsync(calName), string.Format("Error on remvoing calendar - {0}", calName), cancellationToken); } /// @@ -484,11 +518,10 @@ public bool RemoveCalendar(string calName) /// The desired , or null if there is no /// match. /// - public ICalendar RetrieveCalendar(string calName) + public Task RetrieveCalendar(string calName, CancellationToken cancellationToken = default) { - _logger.Info("RetrieveCalendar"); - return DoWithLock(() => _storage.RetrieveCalendar(calName), - string.Format("Error on retrieving calendar - {0}", calName)); + logger.LogInformation("RetrieveCalendar"); + return DoWithLock(() => storage.RetrieveCalendarAsync(calName), string.Format("Error on retrieving calendar - {0}", calName), cancellationToken); } /// @@ -496,10 +529,10 @@ public ICalendar RetrieveCalendar(string calName) /// stored in the . /// /// - public int GetNumberOfJobs() + public Task GetNumberOfJobs(CancellationToken cancellationToken = default) { - _logger.Info("GetNumberOfJobs"); - return DoWithLock(() => _storage.NumberOfJobs(), "Error on getting Number of jobs"); + logger.LogInformation("GetNumberOfJobs"); + return DoWithLock(() => storage.NumberOfJobsAsync(), "Error on getting Number of jobs", cancellationToken); } /// @@ -507,10 +540,10 @@ public int GetNumberOfJobs() /// stored in the . /// /// - public int GetNumberOfTriggers() + public Task GetNumberOfTriggers(CancellationToken cancellationToken = default) { - _logger.Info("GetNumberOfTriggers"); - return DoWithLock(() => _storage.NumberOfTriggers(), "Error on getting number of triggers"); + logger.LogInformation("GetNumberOfTriggers"); + return DoWithLock(() => storage.NumberOfTriggersAsync(), "Error on getting number of triggers", cancellationToken); } /// @@ -518,10 +551,10 @@ public int GetNumberOfTriggers() /// stored in the . /// /// - public int GetNumberOfCalendars() + public Task GetNumberOfCalendars(CancellationToken cancellationToken = default) { - _logger.Info("GetNumberOfCalendars"); - return DoWithLock(() => _storage.NumberOfCalendars(), "Error on getting number of calendars"); + logger.LogInformation("GetNumberOfCalendars"); + return DoWithLock(() => storage.NumberOfCalendarsAsync(), "Error on getting number of calendars", cancellationToken); } /// @@ -534,10 +567,10 @@ public int GetNumberOfCalendars() /// /// /// - public global::Quartz.Collection.ISet GetJobKeys(GroupMatcher matcher) + public Task> GetJobKeys(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("GetJobKeys"); - return DoWithLock(() => _storage.JobKeys(matcher), "Error on getting job keys"); + logger.LogInformation("GetJobKeys"); + return DoWithLock(() => storage.JobKeysAsync(matcher), "Error on getting job keys", cancellationToken); } /// @@ -548,10 +581,10 @@ public int GetNumberOfCalendars() /// zero-length array (not ). /// /// - public global::Quartz.Collection.ISet GetTriggerKeys(GroupMatcher matcher) + public Task> GetTriggerKeys(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("GetTriggerKeys"); - return DoWithLock(() => _storage.TriggerKeys(matcher), "Error on getting trigger keys"); + logger.LogInformation("GetTriggerKeys"); + return DoWithLock(() => storage.TriggerKeysAsync(matcher), "Error on getting trigger keys", cancellationToken); } /// @@ -562,10 +595,10 @@ public int GetNumberOfCalendars() /// array (not ). /// /// - public IList GetJobGroupNames() + public Task> GetJobGroupNames(CancellationToken cancellationToken = default) { - _logger.Info("GetJobGroupNames"); - return DoWithLock(() => _storage.JobGroupNames(), "Error on getting job group names"); + logger.LogInformation("GetJobGroupNames"); + return DoWithLock(() => storage.JobGroupNamesAsync(), "Error on getting job group names", cancellationToken); } /// @@ -576,10 +609,10 @@ public IList GetJobGroupNames() /// array (not ). /// /// - public IList GetTriggerGroupNames() + public Task> GetTriggerGroupNames(CancellationToken cancellationToken = default) { - _logger.Info("GetTriggerGroupNames"); - return DoWithLock(() => _storage.TriggerGroupNames(), "Error on getting trigger group names"); + logger.LogInformation("GetTriggerGroupNames"); + return DoWithLock(() => storage.TriggerGroupNamesAsync(), "Error on getting trigger group names", cancellationToken); } /// @@ -590,10 +623,10 @@ public IList GetTriggerGroupNames() /// a zero-length array (not ). /// /// - public IList GetCalendarNames() + public Task> GetCalendarNames(CancellationToken cancellationToken = default) { - _logger.Info("GetCalendarNames"); - return DoWithLock(() => _storage.CalendarNames(), "Error on getting calendar names"); + logger.LogInformation("GetCalendarNames"); + return DoWithLock(() => storage.CalendarNamesAsync(), "Error on getting calendar names", cancellationToken); } /// @@ -602,31 +635,29 @@ public IList GetCalendarNames() /// /// If there are no matches, a zero-length array should be returned. /// - public IList GetTriggersForJob(JobKey jobKey) + public Task> GetTriggersForJob(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("GetTriggersForJob"); - return DoWithLock(() => _storage.GetTriggersForJob(jobKey), string.Format("Error on getting triggers for job - {0}", jobKey)); + logger.LogInformation("GetTriggersForJob"); + return DoWithLock(() => storage.GetTriggersForJobAsync(jobKey), string.Format("Error on getting triggers for job - {0}", jobKey), cancellationToken); } /// /// Get the current state of the identified . /// /// - public TriggerState GetTriggerState(TriggerKey triggerKey) + public Task GetTriggerState(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("GetTriggerState"); - return DoWithLock(() => _storage.GetTriggerState(triggerKey), - string.Format("Error on getting trigger state for trigger - {0}", triggerKey)); + logger.LogInformation("GetTriggerState"); + return DoWithLock(() => storage.GetTriggerStateAsync(triggerKey), string.Format("Error on getting trigger state for trigger - {0}", triggerKey), cancellationToken); } /// /// Pause the with the given key. /// - public void PauseTrigger(TriggerKey triggerKey) + public Task PauseTrigger(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("PauseTrigger"); - DoWithLock(() => _storage.PauseTrigger(triggerKey), - string.Format("Error on pausing trigger - {0}", triggerKey)); + logger.LogInformation("PauseTrigger"); + return DoWithLock(() => storage.PauseTriggerAsync(triggerKey), string.Format("Error on pausing trigger - {0}", triggerKey), cancellationToken); } /// @@ -638,20 +669,20 @@ public void PauseTrigger(TriggerKey triggerKey) /// pause on any new triggers that are added to the group while the group is /// paused. /// - public global::Quartz.Collection.ISet PauseTriggers(GroupMatcher matcher) + public async Task> PauseTriggers(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("PauseTriggers"); - return DoWithLock(() => new global::Quartz.Collection.HashSet(_storage.PauseTriggers(matcher)), "Error on pausing triggers"); + logger.LogInformation("PauseTriggers"); + return await DoWithLock(() => storage.PauseTriggersAsync(matcher), "Error on pausing triggers", cancellationToken); } /// /// Pause the with the given key - by /// pausing all of its current s. /// - public void PauseJob(JobKey jobKey) + public Task PauseJob(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("PauseJob"); - DoWithLock(() => _storage.PauseJob(jobKey), string.Format("Error on pausing job - {0}", jobKey)); + logger.LogInformation("PauseJob"); + return DoWithLock(() => storage.PauseJobAsync(jobKey), string.Format("Error on pausing job - {0}", jobKey), cancellationToken); } /// @@ -664,10 +695,10 @@ public void PauseJob(JobKey jobKey) /// /// /// - public IList PauseJobs(GroupMatcher matcher) + public Task> PauseJobs(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("PauseJobs"); - return DoWithLock(() => _storage.PauseJobs(matcher), "Error on pausing jobs"); + logger.LogInformation("PauseJobs"); + return DoWithLock(() => storage.PauseJobsAsync(matcher), "Error on pausing jobs", cancellationToken); } /// @@ -679,11 +710,10 @@ public IList PauseJobs(GroupMatcher matcher) /// /// /// - public void ResumeTrigger(TriggerKey triggerKey) + public Task ResumeTrigger(TriggerKey triggerKey, CancellationToken cancellationToken = default) { - _logger.Info("ResumeTrigger"); - DoWithLock(() => _storage.ResumeTrigger(triggerKey), - string.Format("Error on resuming trigger - {0}", triggerKey)); + logger.LogInformation("ResumeTrigger"); + return DoWithLock(() => storage.ResumeTriggerAsync(triggerKey), string.Format("Error on resuming trigger - {0}", triggerKey), cancellationToken); } /// @@ -694,20 +724,20 @@ public void ResumeTrigger(TriggerKey triggerKey) /// 's misfire instruction will be applied. /// /// - public IList ResumeTriggers(GroupMatcher matcher) + public Task> ResumeTriggers(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("ResumeTriggers"); - return DoWithLock(() => _storage.ResumeTriggers(matcher), "Error on resume triggers"); + logger.LogInformation("ResumeTriggers"); + return DoWithLock(() => storage.ResumeTriggersAsync(matcher), "Error on resume triggers", cancellationToken); } /// /// Gets the paused trigger groups. /// /// - public global::Quartz.Collection.ISet GetPausedTriggerGroups() + public Task> GetPausedTriggerGroups(CancellationToken cancellationToken = default) { - _logger.Info("GetPausedTriggerGroups"); - return DoWithLock(() => _storage.GetPausedTriggerGroups(), "Error on getting paused trigger groups"); + logger.LogInformation("GetPausedTriggerGroups"); + return DoWithLock(() => storage.GetPausedTriggerGroupsAsync(), "Error on getting paused trigger groups", cancellationToken); } /// @@ -719,10 +749,10 @@ public IList ResumeTriggers(GroupMatcher matcher) /// instruction will be applied. /// /// - public void ResumeJob(JobKey jobKey) + public Task ResumeJob(JobKey jobKey, CancellationToken cancellationToken = default) { - _logger.Info("ResumeJob"); - DoWithLock(() => _storage.ResumeJob(jobKey), string.Format("Error on resuming job - {0}", jobKey)); + logger.LogInformation("ResumeJob"); + return DoWithLock(() => storage.ResumeJobAsync(jobKey), string.Format("Error on resuming job - {0}", jobKey), cancellationToken); } /// @@ -734,10 +764,10 @@ public void ResumeJob(JobKey jobKey) /// misfire instruction will be applied. /// /// - public global::Quartz.Collection.ISet ResumeJobs(GroupMatcher matcher) + public Task> ResumeJobs(GroupMatcher matcher, CancellationToken cancellationToken = default) { - _logger.Info("ResumeJobs"); - return DoWithLock(() => _storage.ResumeJobs(matcher), "Error on resuming jobs"); + logger.LogInformation("ResumeJobs"); + return DoWithLock(() => storage.ResumeJobsAsync(matcher), "Error on resuming jobs", cancellationToken); } /// @@ -749,10 +779,10 @@ public void ResumeJob(JobKey jobKey) /// /// /// - public void PauseAll() + public Task PauseAll(CancellationToken cancellationToken = default) { - _logger.Info("PauseAll"); - DoWithLock(() => _storage.PauseAllTriggers(), "Error on pausing all"); + logger.LogInformation("PauseAll"); + return DoWithLock(() => storage.PauseAllTriggersAsync(), "Error on pausing all", cancellationToken); } /// @@ -764,10 +794,10 @@ public void PauseAll() /// /// /// - public void ResumeAll() + public Task ResumeAll(CancellationToken cancellationToken = default) { - _logger.Info("ResumeAll"); - DoWithLock(() => _storage.ResumeAllTriggers(), "Error on resuming all"); + logger.LogInformation("ResumeAll"); + return DoWithLock(() => storage.ResumeAllTriggersAsync(), "Error on resuming all", cancellationToken); } /// @@ -779,11 +809,10 @@ public void ResumeAll() /// milliseconds. /// /// - public IList AcquireNextTriggers(DateTimeOffset noLaterThan, int maxCount, TimeSpan timeWindow) + public Task> AcquireNextTriggers(DateTimeOffset noLaterThan, int maxCount, TimeSpan timeWindow, CancellationToken cancellationToken = default) { - _logger.Info("AcquireNextTriggers"); - return DoWithLock(() => _storage.AcquireNextTriggers(noLaterThan, maxCount, timeWindow), - "Error on acquiring next triggers"); + logger.LogInformation("AcquireNextTriggers"); + return DoWithLock(() => storage.AcquireNextTriggersAsync(noLaterThan, maxCount, timeWindow), "Error on acquiring next triggers", cancellationToken); } /// @@ -791,10 +820,10 @@ public IList AcquireNextTriggers(DateTimeOffset noLaterThan, i /// fire the given , that it had previously acquired /// (reserved). /// - public void ReleaseAcquiredTrigger(IOperableTrigger trigger) + public Task ReleaseAcquiredTrigger(IOperableTrigger trigger, CancellationToken cancellationToken = default) { - _logger.Info("ReleaseAcquiredTrigger"); - DoWithLock(() => _storage.ReleaseAcquiredTrigger(trigger), string.Format("Error on releasing acquired trigger - {0}", trigger)); + logger.LogInformation("ReleaseAcquiredTrigger"); + return DoWithLock(() => storage.ReleaseAcquiredTriggerAsync(trigger), string.Format("Error on releasing acquired trigger - {0}", trigger), cancellationToken); } /// @@ -808,10 +837,10 @@ public void ReleaseAcquiredTrigger(IOperableTrigger trigger) /// state. Preference is to return an empty list if none of the triggers /// could be fired. /// - public IList TriggersFired(IList triggers) + public Task> TriggersFired(IReadOnlyCollection triggers, CancellationToken cancellationToken = default) { - _logger.Info("TriggersFired"); - return DoWithLock(() => _storage.TriggersFired(triggers), "Error on Triggers Fired"); + logger.LogInformation("TriggersFired"); + return DoWithLock(() => storage.TriggersFiredAsync(triggers), "Error on Triggers Fired", cancellationToken); } /// @@ -821,35 +850,33 @@ public IList TriggersFired(IList triggers) /// in the given should be updated if the /// is stateful. /// - public void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail jobDetail, SchedulerInstruction triggerInstCode) + public Task TriggeredJobComplete(IOperableTrigger trigger, IJobDetail jobDetail, SchedulerInstruction triggerInstCode, CancellationToken cancellationToken = default) { - _logger.Info("TriggeredJobComplete"); - DoWithLock(() => _storage.TriggeredJobComplete(trigger, jobDetail, triggerInstCode), - string.Format("Error on triggered job complete - job:{0} - trigger:{1}", jobDetail, trigger)); + logger.LogInformation("TriggeredJobComplete"); + return DoWithLock(() => storage.TriggeredJobCompleteAsync(trigger, jobDetail, triggerInstCode), string.Format("Error on triggered job complete - job:{0} - trigger:{1}", jobDetail, trigger), cancellationToken); } - - #endregion - #region private methods /// /// crud opertion to redis with lock /// /// return type of the Function - /// Fuction + /// Fuction /// error message used to override the default one /// - private T DoWithLock(Func fun, string errorMessage = "Job Storage error") + async Task DoWithLock(Func> asyncFunction, string errorMessage = "Job Storage error", CancellationToken cancellationToken = default) { + string lockValue = null; try { - _storage.LockWithWait(); - return fun.Invoke(); + lockValue = await storage.LockWithWait(cancellationToken); + return await asyncFunction.Invoke(); } - catch (ObjectAlreadyExistsException) + catch (ObjectAlreadyExistsException ex) { + logger.Log(LogLevel.Error, ex, "key exists"); throw; } catch (Exception ex) @@ -858,25 +885,28 @@ private T DoWithLock(Func fun, string errorMessage = "Job Storage error") } finally { - _storage.Unlock(); + if (lockValue != null) + await storage.UnlockAsync(lockValue); } } /// /// crud opertion to redis with lock /// - /// Action + /// Action /// error message used to override the default one - private void DoWithLock(Action action, string errorMessage = "Job Storage error") + async Task DoWithLock(Func asyncAction, string errorMessage = "Job Storage error", CancellationToken cancellationToken = default) { + string lockValue = null; try { - _storage.LockWithWait(); - action.Invoke(); + lockValue = await storage.LockWithWait(cancellationToken); + await asyncAction.Invoke(); } catch (ObjectAlreadyExistsException ex) { - _logger.Error("key exists", ex); + logger.Log(LogLevel.Error, ex, "key exists"); + throw; } catch (Exception ex) { @@ -884,10 +914,27 @@ private void DoWithLock(Action action, string errorMessage = "Job Storage error" } finally { - _storage.Unlock(); + if (lockValue != null) + await storage.UnlockAsync(lockValue); } } + public void Dispose() + { + db?.Multiplexer.Dispose(); + db = null; + } #endregion } + + public class NullLogger : ILogger + { + public static ILogger Instance { get; } = new NullLogger(); + + public IDisposable BeginScope(TState state) => null; + public bool IsEnabled(LogLevel logLevel) => false; + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + } + } } diff --git a/QuartzRedisJobStore.JobStore/RedisJobStoreSchema.cs b/QuartzRedisJobStore.JobStore/RedisJobStoreSchema.cs index 6d3ef14..26573b8 100644 --- a/QuartzRedisJobStore.JobStore/RedisJobStoreSchema.cs +++ b/QuartzRedisJobStore.JobStore/RedisJobStoreSchema.cs @@ -1,19 +1,18 @@ -using System; +using Quartz; +using System; using System.Collections.Generic; -using System.Linq; -using Quartz; namespace QuartzRedisJobStore.JobStore { /// /// schema class for creating keys for hash, set etc. /// - public class RedisJobStoreSchema { - + public class RedisJobStoreSchema + { /// /// Default lock name /// - private const string DefaultLockName = "lock"; + const string DefaultLockName = "lock"; #region Job related key names /// @@ -45,11 +44,11 @@ public class RedisJobStoreSchema { /// /// set name for jobs /// - private const string JobsSet = "jobs"; + const string JobsSet = "jobs"; /// /// set name for all the groups who have jobs. /// - private const string JobGroupsSet = "job_groups"; + const string JobGroupsSet = "job_groups"; #endregion #region trigger related key names @@ -123,7 +122,7 @@ public class RedisJobStoreSchema { /// public const string TimesTriggered = "times_triggered"; - + /// /// hash value - Cron Trigger Type string /// @@ -146,23 +145,24 @@ public class RedisJobStoreSchema { /// /// Default Delimiter /// - private const string DefaultDelimiter = ":"; + const string DefaultDelimiter = ":"; /// /// name for prefix used to support different schedulers /// - private readonly string _prefix; + readonly string prefix; /// /// delimiter /// - private readonly string _delimiter; + readonly string delimiter; + + readonly string escapedDelimiter; /// /// constructor, with no prefix /// - public RedisJobStoreSchema() - : this(string.Empty) + public RedisJobStoreSchema() : this(string.Empty) { } @@ -171,8 +171,7 @@ public RedisJobStoreSchema() /// constructor with the customized prefix /// /// prefix - public RedisJobStoreSchema(string prefix) - : this(prefix, DefaultDelimiter) + public RedisJobStoreSchema(string prefix) : this(prefix, DefaultDelimiter) { } @@ -184,8 +183,11 @@ public RedisJobStoreSchema(string prefix) /// delimiter public RedisJobStoreSchema(string prefix, string delimiter) { - _prefix = prefix; - _delimiter = delimiter; + this.prefix = prefix; + this.delimiter = delimiter; + escapedDelimiter = delimiter.Contains(":") + ? delimiter.Replace(":", "\\;") + : delimiter; } /// @@ -195,7 +197,7 @@ public RedisJobStoreSchema(string prefix, string delimiter) /// hash key public string JobHashKey(JobKey jobKey) { - return this.AddPrefix("job" + _delimiter + jobKey.Group + _delimiter + jobKey.Name); + return AddPrefix("job", jobKey.Group, jobKey.Name); } /// @@ -205,7 +207,7 @@ public string JobHashKey(JobKey jobKey) /// hash key public string JobDataMapHashKey(JobKey jobKey) { - return this.AddPrefix("job_data_map" + _delimiter + jobKey.Group + _delimiter + jobKey.Name); + return AddPrefix("job_data_map", jobKey.Group, jobKey.Name); } /// @@ -213,29 +215,29 @@ public string JobDataMapHashKey(JobKey jobKey) /// /// Group Name /// key for the set - public String JobGroupSetKey(string groupName) + public string JobGroupSetKey(string groupName) { - return AddPrefix("job_group" + _delimiter + groupName); + return AddPrefix("job_group", groupName); } - + /// /// set key for holding all the jobs. /// /// set key - public String JobsSetKey() + public string JobsSetKey() { - return this.AddPrefix(JobsSet); + return AddPrefix(JobsSet); } /// /// set kye for holding all the job groups /// /// set key - public String JobGroupsSetKey() + public string JobGroupsSetKey() { - return this.AddPrefix(JobGroupsSet); + return AddPrefix(JobGroupsSet); } /// @@ -243,9 +245,10 @@ public String JobGroupsSetKey() /// /// hash key for a job /// JobKey - public JobKey JobKey(string jobHashKey){ - var hashParts = this.Split(jobHashKey); - return new JobKey(hashParts[2], hashParts[1]); + public JobKey JobKey(string jobHashKey) + { + var (name, group) = Split(jobHashKey); + return new JobKey(name, group); } /// @@ -264,7 +267,7 @@ public string BlockedJobsSet() /// set key public string JobTriggersSetKey(JobKey jobKey) { - return this.AddPrefix("job_triggers" + _delimiter + jobKey.Group + _delimiter + jobKey.Name); + return AddPrefix("job_triggers", jobKey.Group, jobKey.Name); } /// @@ -274,7 +277,7 @@ public string JobTriggersSetKey(JobKey jobKey) /// hash key public string TriggerHashkey(TriggerKey triggerKey) { - return this.AddPrefix("trigger" + _delimiter + triggerKey.Group + _delimiter + triggerKey.Name); + return AddPrefix("trigger", triggerKey.Group, triggerKey.Name); } /// @@ -282,8 +285,9 @@ public string TriggerHashkey(TriggerKey triggerKey) /// /// triggerGroupSetKey /// Trigger group name - public String TriggerGroup(string triggerGroupSetKey){ - return this.Split(triggerGroupSetKey)[1]; + public string TriggerGroup(string triggerGroupSetKey) + { + return Split(triggerGroupSetKey).group; } /// @@ -293,7 +297,7 @@ public String TriggerGroup(string triggerGroupSetKey){ /// set key public string TriggerGroupSetKey(string group) { - return this.AddPrefix("trigger_group" + _delimiter + group); + return AddPrefix("trigger_group", group); } /// @@ -302,14 +306,14 @@ public string TriggerGroupSetKey(string group) /// set key public string TriggersSetKey() { - return this.AddPrefix("triggers"); + return AddPrefix("triggers"); } /// /// a set key which holds all the trigger_groups /// /// set key - public String TriggerGroupsSetKey() + public string TriggerGroupsSetKey() { return AddPrefix("trigger_groups"); } @@ -327,7 +331,7 @@ public string PausedTriggerGroupsSetKey() /// a set key which holds all the job groups whose state are paused. /// /// set key - public String PausedJobGroupsSetKey() + public string PausedJobGroupsSetKey() { return AddPrefix("paused_job_groups"); } @@ -337,10 +341,10 @@ public String PausedJobGroupsSetKey() /// /// Trigger Hash Key /// TriggerKey - public TriggerKey TriggerKey(String triggerHashKey) + public TriggerKey TriggerKey(string triggerHashKey) { - var hashParts = triggerHashKey.Split(new[] { _delimiter }, StringSplitOptions.None); - return new TriggerKey(hashParts[2], hashParts[1]); + var (name, group) = Split(triggerHashKey); + return new TriggerKey(name, group); } /// @@ -350,7 +354,7 @@ public TriggerKey TriggerKey(String triggerHashKey) /// sorted set key public string TriggerStateSetKey(RedisTriggerState triggerState) { - return this.AddPrefix(triggerState.GetDisplayName()); + return AddPrefix(triggerState.GetDisplayName()); } /// @@ -358,9 +362,9 @@ public string TriggerStateSetKey(RedisTriggerState triggerState) /// /// TriggerKey /// a key - public String TriggerLockKey(TriggerKey triggerKey) + public string TriggerLockKey(TriggerKey triggerKey) { - return AddPrefix("trigger_lock" + _delimiter + triggerKey.Group + _delimiter + triggerKey.Name); + return AddPrefix("trigger_lock", triggerKey.Group, triggerKey.Name); } /// @@ -368,8 +372,9 @@ public String TriggerLockKey(TriggerKey triggerKey) /// /// JobKey /// a key - public String JobBlockedKey(JobKey jobKey){ - return AddPrefix("job_blocked" + _delimiter + jobKey.Group + _delimiter + jobKey.Name); + public string JobBlockedKey(JobKey jobKey) + { + return AddPrefix("job_blocked", jobKey.Group, jobKey.Name); } /// @@ -379,7 +384,7 @@ public String JobBlockedKey(JobKey jobKey){ /// set key public string CalendarTriggersSetKey(string calendarName) { - return AddPrefix("calendar_triggers" + _delimiter + calendarName); + return AddPrefix("calendar_triggers", calendarName); } @@ -390,7 +395,7 @@ public string CalendarTriggersSetKey(string calendarName) /// hash key public string CalendarHashKey(string calendarName) { - return AddPrefix("calendar" + _delimiter + calendarName); + return AddPrefix("calendar", calendarName); } /// @@ -400,7 +405,7 @@ public string CalendarHashKey(string calendarName) /// Calendar Name public string GetCalendarName(string calendarHashKey) { - return Split(calendarHashKey)[1]; + return Split(calendarHashKey).group; } /// @@ -417,39 +422,45 @@ public string CalendarsSetKey() /// /// jobGroupSetKey /// Job's Group - public String JobGroup(string jobGroupSetKey){ - return Split(jobGroupSetKey)[1]; + public string JobGroup(string jobGroupSetKey) + { + return Split(jobGroupSetKey).group; } /// /// construct a key for LastTriggerReleaseTime which is used to check for releaseing the orphaned triggers. /// /// - public String LastTriggerReleaseTime() + public string LastTriggerReleaseTime() { return AddPrefix("last_triggers_release_time"); } - + /// /// get the lock key for redis. /// - public string LockKey - { - get - { - return this.AddPrefix(DefaultLockName); - } - } + public string LockKey => AddPrefix(DefaultLockName); /// /// prefix the keys /// /// key /// key in redis - private String AddPrefix(String key) + private string AddPrefix(string key, string group = null, string name = null) { - return _prefix + key; + return prefix + string.Join(delimiter, GetValues()); + + IEnumerable GetValues() + { + yield return key.Replace(delimiter, escapedDelimiter); + + if (!string.IsNullOrEmpty(group)) + yield return group.Replace(delimiter, escapedDelimiter); + + if (!string.IsNullOrEmpty(name)) + yield return name.Replace(delimiter, escapedDelimiter); + } } /// @@ -457,9 +468,13 @@ private String AddPrefix(String key) /// /// /// - internal List Split(string val) + internal (string name, string group) Split(string val) { - return (val.Split(new [] { _delimiter }, StringSplitOptions.None)).ToList(); + if (!val.StartsWith(prefix)) + throw new ArgumentException($"Invalid key {val}, does not start with prefix {prefix}"); + + var parts = val.Substring(prefix.Length).Split(new[] { delimiter }, 3, StringSplitOptions.None); + return (parts.Length > 2 ? parts[2].Replace(escapedDelimiter, delimiter) : null, parts[1].Replace(escapedDelimiter, delimiter)); } } } diff --git a/QuartzRedisJobStore.JobStore/RedisStorage.cs b/QuartzRedisJobStore.JobStore/RedisStorage.cs index d00b8ae..79eb2e8 100644 --- a/QuartzRedisJobStore.JobStore/RedisStorage.cs +++ b/QuartzRedisJobStore.JobStore/RedisStorage.cs @@ -1,6 +1,11 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.Extensions.Logging; using Quartz; using Quartz.Impl.Matchers; using Quartz.Spi; @@ -13,7 +18,6 @@ namespace QuartzRedisJobStore.JobStore /// public class RedisStorage : BaseJobStorage { - #region constructor /// /// Constructor @@ -24,7 +28,10 @@ public class RedisStorage : BaseJobStorage /// SchedulerInstanceId /// triggerLockTimeout /// redisLockTimeout - public RedisStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout) : base(redisJobStoreSchema, db, signaler, schedulerInstanceId, triggerLockTimeout, redisLockTimeout) { } + public RedisStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISchedulerSignaler signaler, string schedulerInstanceId, int triggerLockTimeout, int redisLockTimeout, ILogger logger) : + base(redisJobStoreSchema, db, signaler, schedulerInstanceId, triggerLockTimeout, redisLockTimeout, logger) + { + } #endregion @@ -33,76 +40,69 @@ public RedisStorage(RedisJobStoreSchema redisJobStoreSchema, IDatabase db, ISche /// Store the given . /// /// The to be stored.If , any existing in the - /// with the same name and group should be - /// over-written. + /// with the same name and group should be over-written. /// - public override void StoreJob(IJobDetail jobDetail, bool replaceExisting) + /// ObjectAlreadyExistsException + public override async Task StoreJobAsync(IJobDetail jobDetail, bool replaceExisting) { - var jobHashKey = RedisJobStoreSchema.JobHashKey(jobDetail.Key); - var jobDataMapHashKey = RedisJobStoreSchema.JobDataMapHashKey(jobDetail.Key); - var jobGroupSetKey = RedisJobStoreSchema.JobGroupSetKey(jobDetail.Key.Group); + var jobHashKey = redisJobStoreSchema.JobHashKey(jobDetail.Key); + var jobDataMapHashKey = redisJobStoreSchema.JobDataMapHashKey(jobDetail.Key); + var jobGroupSetKey = redisJobStoreSchema.JobGroupSetKey(jobDetail.Key.Group); - if (Db.KeyExists(jobHashKey) && !replaceExisting) - { + if (await db.KeyExistsAsync(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); + await db.HashSetAsync(jobHashKey, ConvertToHashEntries(jobDetail)); + await db.HashSetAsync(jobDataMapHashKey, ConvertToHashEntries(jobDetail.JobDataMap)); + await db.SetAddAsync(redisJobStoreSchema.JobsSetKey(), jobHashKey); + await db.SetAddAsync(redisJobStoreSchema.JobGroupsSetKey(), jobGroupSetKey); + await db.SetAddAsync(jobGroupSetKey, jobHashKey); } /// /// Store the given . /// - /// The to be stored.If , any existing in - /// the with the same name and group should - /// be over-written.ObjectAlreadyExistsException - public override void StoreTrigger(ITrigger trigger, bool replaceExisting) + /// The to be stored. + /// If , any existing in the + /// with the same name and group should be over-written. + /// ObjectAlreadyExistsException + public override async Task StoreTriggerAsync(ITrigger trigger, bool replaceExisting) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(trigger.Key); - var triggerGroupSetKey = RedisJobStoreSchema.TriggerGroupSetKey(trigger.Key.Group); - var jobTriggerSetKey = RedisJobStoreSchema.JobTriggersSetKey(trigger.JobKey); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(trigger.Key); + var triggerGroupSetKey = redisJobStoreSchema.TriggerGroupSetKey(trigger.Key.Group); + var jobTriggerSetKey = redisJobStoreSchema.JobTriggersSetKey(trigger.JobKey); + var jobHashKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); - if (((trigger is ISimpleTrigger) == false) && ((trigger is ICronTrigger) == false)) - { + if (!(trigger is ISimpleTrigger) && !(trigger is ICronTrigger)) throw new NotImplementedException("Unknown trigger, only SimpleTrigger and CronTrigger are supported"); - } - var triggerExists = Db.KeyExists(triggerHashKey); + + var triggerExists = await db.KeyExistsAsync(triggerHashKey); if (triggerExists && replaceExisting == false) - { throw new ObjectAlreadyExistsException(trigger); - } + if (!await db.KeyExistsAsync(jobHashKey)) + throw new JobPersistenceException(string.Format("Job with key {0} does not exist", jobHashKey)); - Db.HashSet(triggerHashKey, ConvertToHashEntries(trigger)); - Db.SetAdd(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey); - Db.SetAdd(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey); - Db.SetAdd(triggerGroupSetKey, triggerHashKey); - Db.SetAdd(jobTriggerSetKey, triggerHashKey); + await db.HashSetAsync(triggerHashKey, ConvertToHashEntries(trigger)); + await db.SetAddAsync(redisJobStoreSchema.TriggersSetKey(), triggerHashKey); + await db.SetAddAsync(redisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey); + await db.SetAddAsync(triggerGroupSetKey, triggerHashKey); + await db.SetAddAsync(jobTriggerSetKey, triggerHashKey); - if(!string.IsNullOrEmpty(trigger.CalendarName)) { - var calendarTriggersSetKey = RedisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName); - Db.SetAdd(calendarTriggersSetKey, triggerHashKey); + if(!string.IsNullOrEmpty(trigger.CalendarName)) + { + var calendarTriggersSetKey = redisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName); + await db.SetAddAsync(calendarTriggersSetKey, triggerHashKey); } //if trigger already exists, remove it from all the possible states. if (triggerExists) - { - this.UnsetTriggerState(triggerHashKey); - } + await UnsetTriggerStateAsync(triggerHashKey); //then update it with the new state in the its respectvie sorted set. - UpdateTriggerState(trigger); + await UpdateTriggerStateAsync(trigger); } /// @@ -110,145 +110,122 @@ public override void StoreTrigger(ITrigger trigger, bool replaceExisting) /// /// trigger hash key /// succeeds or not - public override bool UnsetTriggerState(string triggerHashKey) + public override async Task UnsetTriggerStateAsync(string triggerHashKey) { + var wasRemoved = false; + var result = false; + foreach(var state in Enum.GetValues(typeof(RedisTriggerState)).OfType()) + wasRemoved |= await db.SortedSetRemoveAsync(redisJobStoreSchema.TriggerStateSetKey(state), 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))); - } + if (wasRemoved) + result = await db.KeyDeleteAsync(redisJobStoreSchema.TriggerLockKey(redisJobStoreSchema.TriggerKey(triggerHashKey))); - return false; + return result; } /// /// Store the given . /// - /// The name.The to be stored.If , any existing - /// in the with the same name and group - /// should be over-written.If , any s existing - /// in the that reference an existing - /// Calendar with the same name with have their next fire time - /// re-computed with the new .ObjectAlreadyExistsException - public override void StoreCalendar(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers) + /// The name. + /// The to be stored. + /// If , any existing in the + /// with the same name and group should be over-written. + /// If , any s existing in the + /// that reference an existing Calendar with the same name with have their next fire time re-computed with the new . + /// ObjectAlreadyExistsException + public override async Task StoreCalendarAsync(string name, ICalendar calendar, bool replaceExisting, bool updateTriggers) { - string calendarHashKey = RedisJobStoreSchema.CalendarHashKey(name); + var calendarHashKey = redisJobStoreSchema.CalendarHashKey(name); - if (replaceExisting == false && Db.KeyExists(calendarHashKey)) - { + if (replaceExisting == false && await db.KeyExistsAsync(calendarHashKey)) throw new ObjectAlreadyExistsException(string.Format("Calendar with key {0} already exists", calendarHashKey)); - } - Db.HashSet(calendarHashKey, ConvertToHashEntries(calendar)); - Db.SetAdd(RedisJobStoreSchema.CalendarsSetKey(), calendarHashKey); + await db.HashSetAsync(calendarHashKey, ConvertToHashEntries(calendar)); + await db.SetAddAsync(redisJobStoreSchema.CalendarsSetKey(), calendarHashKey); if (updateTriggers) { - var calendarTriggersSetkey = RedisJobStoreSchema.CalendarTriggersSetKey(name); + var calendarTriggersSetkey = redisJobStoreSchema.CalendarTriggersSetKey(name); - var triggerHashKeys = Db.SetMembers(calendarTriggersSetkey); + 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); + var trigger = await RetrieveTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey)); + trigger.UpdateWithNewCalendar(calendar, TimeSpan.FromSeconds(misfireThreshold)); + await StoreTriggerAsync(trigger, true); } } - } /// - /// Remove (delete) the with the - /// given name. + /// Remove (delete) the with the given name. /// /// - /// If removal of the would result in - /// s pointing to non-existent calendars, then a - /// will be thrown. + /// If removal of the would result in s pointing to non-existent calendars, then a + /// will be thrown. /// /// The name of the to be removed. /// - /// if a with the given name - /// was found and removed from the store. + /// if a with the given name was found and removed from the store. /// - public override bool RemoveCalendar(string calendarName) + public override async Task RemoveCalendarAsync(string calendarName) { - var calendarTriggersSetKey = RedisJobStoreSchema.CalendarTriggersSetKey(calendarName); + var calendarTriggersSetKey = redisJobStoreSchema.CalendarTriggersSetKey(calendarName); - if (Db.SetLength(calendarTriggersSetKey) > 0) - { - throw new JobPersistenceException(string.Format("There are triggers are using calendar {0}", - calendarName)); - } + if (await db.SetLengthAsync(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); + var calendarHashKey = redisJobStoreSchema.CalendarHashKey(calendarName); + return await db.KeyDeleteAsync(calendarHashKey) && await db.SetRemoveAsync(redisJobStoreSchema.CalendarsSetKey(), calendarHashKey); } /// - /// Remove (delete) the with the given - /// key, and any s that reference - /// it. + /// Remove (delete) the with the given key, and any s that reference it. /// /// - /// If removal of the results in an empty group, the - /// group should be removed from the 's list of - /// known group names. + /// If removal of the results in an empty group, the group should be removed from the + /// 's list of known group names. /// /// - /// if a with the given name and - /// group was found and removed from the store. + /// if a with the given name and group was found and removed from the store. /// - public override bool RemoveJob(JobKey jobKey) + public override async Task RemoveJobAsync(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); + var jobHashKey = redisJobStoreSchema.JobHashKey(jobKey); + var jobDataMapHashKey = redisJobStoreSchema.JobDataMapHashKey(jobKey); + var jobGroupSetKey = redisJobStoreSchema.JobGroupSetKey(jobKey.Group); + var jobTriggerSetKey = redisJobStoreSchema.JobTriggersSetKey(jobKey); - Db.SetRemove(RedisJobStoreSchema.JobsSetKey(), jobHashKey); + var delJobHashKeyResult = await db.KeyDeleteAsync(jobHashKey); - Db.SetRemove(jobGroupSetKey, jobHashKey); + await db.KeyDeleteAsync(jobDataMapHashKey); + await db.SetRemoveAsync(redisJobStoreSchema.JobsSetKey(), jobHashKey); + await db.SetRemoveAsync(jobGroupSetKey, jobHashKey); - var jobTriggerSetResult = Db.SetMembers(jobTriggerSetKey); + var jobTriggerSetResult = db.SetMembers(jobTriggerSetKey); - Db.KeyDelete(jobTriggerSetKey); + await db.KeyDeleteAsync(jobTriggerSetKey); - var jobGroupSetLengthResult = Db.SetLength(jobGroupSetKey); + var jobGroupSetLengthResult = await db.SetLengthAsync(jobGroupSetKey); if (jobGroupSetLengthResult == 0) - { - Db.SetRemoveAsync(RedisJobStoreSchema.JobGroupsSetKey(), jobGroupSetKey); - } + await 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); + var triggerkey = redisJobStoreSchema.TriggerKey(triggerHashKey); + var triggerGroupKey = redisJobStoreSchema.TriggerGroupSetKey(triggerkey.Group); - this.UnsetTriggerState(triggerHashKey); + await UnsetTriggerStateAsync(triggerHashKey); - Db.SetRemove(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey); - - Db.SetRemove(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupKey); - - Db.SetRemove(RedisJobStoreSchema.TriggerGroupSetKey(triggerkey.Group), triggerHashKey); - - Db.KeyDelete(triggerHashKey.ToString()); + await db.SetRemoveAsync(redisJobStoreSchema.TriggersSetKey(), triggerHashKey); + await db.SetRemoveAsync(redisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupKey); + await db.SetRemoveAsync(redisJobStoreSchema.TriggerGroupSetKey(triggerkey.Group), triggerHashKey); + await db.KeyDeleteAsync(triggerHashKey.ToString()); } return delJobHashKeyResult; @@ -259,39 +236,38 @@ public override bool RemoveJob(JobKey jobKey) /// Pause the with the given key - by /// pausing all of its current s. /// - public override IList PauseJobs(GroupMatcher matcher) + public override async Task> PauseJobsAsync(GroupMatcher matcher) { var pausedJobGroups = new List(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var jobGroupSetKey = RedisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); + var jobGroupSetKey = redisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); - if (Db.SetAdd(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey)) + if (await db.SetAddAsync(redisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey)) { - pausedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroupSetKey)); + pausedJobGroups.Add(redisJobStoreSchema.JobGroup(jobGroupSetKey)); - foreach (RedisValue val in Db.SetMembers(jobGroupSetKey)) - { - PauseJob(RedisJobStoreSchema.JobKey(val)); - } + foreach (var val in await db.SetMembersAsync(jobGroupSetKey)) + await PauseJobAsync(redisJobStoreSchema.JobKey(val)); } } else { - var jobGroupSets = Db.SetMembers(RedisJobStoreSchema.JobGroupsSetKey()); + var allJobGroups = await db.SetMembersAsync(redisJobStoreSchema.JobGroupsSetKey()); + var filteredJobGroups = allJobGroups.Where(jobGroupSet => matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.JobGroup(jobGroupSet), matcher.CompareToValue)); - var jobGroups = jobGroupSets.Where(jobGroupSet => matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.JobGroup(jobGroupSet), matcher.CompareToValue)).ToDictionary(jobGroupSet => jobGroupSet, jobGroupSet => Db.SetMembers(jobGroupSet.ToString())); - - foreach (var jobGroup in jobGroups) + foreach (var jobGroup in filteredJobGroups) { - if (Db.SetAdd(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroup.Key)) - { - pausedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroup.Key)); + var jobs = await db.SetMembersAsync(jobGroup.ToString()); - foreach (var jobHashKey in jobGroup.Value) + if (await db.SetAddAsync(redisJobStoreSchema.PausedJobGroupsSetKey(), jobGroup)) + { + pausedJobGroups.Add(redisJobStoreSchema.JobGroup(jobGroup)); + if (jobs != null) { - PauseJob(RedisJobStoreSchema.JobKey(jobHashKey)); + foreach (var jobHashKey in jobs) + await PauseJobAsync(redisJobStoreSchema.JobKey(jobHashKey)); } } } @@ -310,98 +286,74 @@ public override IList PauseJobs(GroupMatcher matcher) /// misfire instruction will be applied. /// /// - public override global::Quartz.Collection.ISet ResumeJobs(GroupMatcher matcher) + public override async Task> ResumeJobsAsync(GroupMatcher matcher) { var resumedJobGroups = new List(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var jobGroupSetKey = RedisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); + var jobGroupSetKey = redisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); - var removedPausedResult = Db.SetRemove(RedisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey); - var jobsResult = Db.SetMembers(jobGroupSetKey); + var removedPausedResult = await db.SetRemoveAsync(redisJobStoreSchema.PausedJobGroupsSetKey(), jobGroupSetKey); + var jobsResult = await db.SetMembersAsync(jobGroupSetKey); if (removedPausedResult) - { - resumedJobGroups.Add(RedisJobStoreSchema.JobGroup(jobGroupSetKey)); - } + resumedJobGroups.Add(redisJobStoreSchema.JobGroup(jobGroupSetKey)); foreach (var job in jobsResult) - { - ResumeJob(RedisJobStoreSchema.JobKey(job)); - } + await ResumeJobAsync(redisJobStoreSchema.JobKey(job)); } else { - foreach (var jobGroupSetKey in Db.SetMembers(RedisJobStoreSchema.JobGroupsSetKey())) + foreach (var jobGroupSetKey in await db.SetMembersAsync(redisJobStoreSchema.JobGroupsSetKey())) { - if (matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.JobGroup(jobGroupSetKey), - matcher.CompareToValue)) - { - - resumedJobGroups.AddRange(ResumeJobs( - GroupMatcher.GroupEquals(RedisJobStoreSchema.JobGroup(jobGroupSetKey)))); - } + if (matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.JobGroup(jobGroupSetKey), matcher.CompareToValue)) + resumedJobGroups.AddRange(await ResumeJobsAsync(GroupMatcher.GroupEquals(redisJobStoreSchema.JobGroup(jobGroupSetKey)))); } } - return new global::Quartz.Collection.HashSet(resumedJobGroups); + return new HashSet(resumedJobGroups); } /// - /// Resume (un-pause) the with the - /// given key. + /// Resume (un-pause) the with the given key. /// /// If the missed one or more fire-times, then the /// 's misfire instruction will be applied. /// /// /// - public override void ResumeTrigger(TriggerKey triggerKey) + public override async Task ResumeTriggerAsync(TriggerKey triggerKey) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerExists = await db.SetContainsAsync(redisJobStoreSchema.TriggersSetKey(), triggerHashKey); + var isPausedTrigger = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused), triggerHashKey); + var isPausedBlockedTrigger = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked), triggerHashKey); - 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) - { + if (!triggerExists) return; - } //Trigger is not paused, cant be resumed then. if (!isPausedTrigger.HasValue && !isPausedBlockedTrigger.HasValue) - { return; - } - var trigger = RetrieveTrigger(triggerKey); + var trigger = await RetrieveTriggerAsync(triggerKey); - var jobHashKey = RedisJobStoreSchema.JobHashKey(trigger.JobKey); + var jobHashKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); var nextFireTime = trigger.GetNextFireTimeUtc(); if (nextFireTime.HasValue) { + var newTriggerState = await db.SetContainsAsync(redisJobStoreSchema.BlockedJobsSet(), jobHashKey) + ? RedisTriggerState.Blocked + : RedisTriggerState.Waiting; - if (Db.SetContains(RedisJobStoreSchema.BlockedJobsSet(), jobHashKey)) - { - SetTriggerState(RedisTriggerState.Blocked, nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); - } - else - { - SetTriggerState(RedisTriggerState.Waiting, nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); - } + await SetTriggerStateAsync(newTriggerState, nextFireTime.Value.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); } - ApplyMisfire(trigger); + + await ApplyMisfireAsync(trigger); } /// @@ -420,61 +372,51 @@ public override void ResumeTrigger(TriggerKey triggerKey) /// /// /// - /// if a with the given - /// name and group was found and removed from the store. + /// if a with the given name and group was found and removed from the store. /// - public override bool RemoveTrigger(TriggerKey triggerKey, bool removeNonDurableJob = true) + public override async Task RemoveTriggerAsync(TriggerKey triggerKey, bool removeNonDurableJob = true) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(triggerKey); - if (!Db.KeyExists(triggerHashKey)) - { + if (!await db.KeyExistsAsync(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); + var trigger = await RetrieveTriggerAsync(triggerKey); - Db.SetRemove(RedisJobStoreSchema.TriggersSetKey(), triggerHashKey); + var triggerGroupSetKey = redisJobStoreSchema.TriggerGroupSetKey(triggerKey.Group); + var jobHashKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); + var jobTriggerSetkey = redisJobStoreSchema.JobTriggersSetKey(trigger.JobKey); - Db.SetRemove(triggerGroupSetKey, triggerHashKey); + await db.SetRemoveAsync(redisJobStoreSchema.TriggersSetKey(), triggerHashKey); + await db.SetRemoveAsync(triggerGroupSetKey, triggerHashKey); + await db.SetRemoveAsync(jobTriggerSetkey, triggerHashKey); - Db.SetRemove(jobTriggerSetkey, triggerHashKey); - - if (Db.SetLength(triggerGroupSetKey) == 0) - { - Db.SetRemove(RedisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey); - } + if (await db.SetLengthAsync(triggerGroupSetKey) == 0) + await db.SetRemoveAsync(redisJobStoreSchema.TriggerGroupsSetKey(), triggerGroupSetKey); if (removeNonDurableJob) { + var jobTriggerSetKeyLengthResult = await db.SetLengthAsync(jobTriggerSetkey); - var jobTriggerSetKeyLengthResult = Db.SetLength(jobTriggerSetkey); - - var jobExistsResult = Db.KeyExists(jobHashKey); + var jobExistsResult = await db.KeyExistsAsync(jobHashKey); if (jobTriggerSetKeyLengthResult == 0 && jobExistsResult) { - var job = RetrieveJob(trigger.JobKey); + var job = await RetrieveJobAsync(trigger.JobKey); - if (job.Durable == false) + if (!job.Durable) { - RemoveJob(job.Key); - SchedulerSignaler.NotifySchedulerListenersJobDeleted(job.Key); + await RemoveJobAsync(job.Key); + await signaler.NotifySchedulerListenersJobDeleted(job.Key); } } } if (!string.IsNullOrEmpty(trigger.CalendarName)) - { - Db.SetRemove(RedisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName), triggerHashKey); - } + await db.SetRemoveAsync(redisJobStoreSchema.CalendarTriggersSetKey(trigger.CalendarName), triggerHashKey); - this.UnsetTriggerState(triggerHashKey); - return Db.KeyDelete(triggerHashKey); + await UnsetTriggerStateAsync(triggerHashKey); + return await db.KeyDeleteAsync(triggerHashKey); } /// @@ -485,86 +427,63 @@ public override bool RemoveTrigger(TriggerKey triggerKey, bool removeNonDurableJ /// 's misfire instruction will be applied. /// /// - public override IList ResumeTriggers(GroupMatcher matcher) + public override async Task> ResumeTriggersAsync(GroupMatcher matcher) { var resumedTriggerGroups = new List(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var triggerGroupSetKey = - RedisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); + var triggerGroupSetKey = redisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); - Db.SetRemove(RedisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroupSetKey); + await db.SetRemoveAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroupSetKey); - var triggerHashKeysResult = Db.SetMembers(triggerGroupSetKey); + var triggerHashKeysResult = await db.SetMembersAsync(triggerGroupSetKey); foreach (var triggerHashKey in triggerHashKeysResult) { - var trigger = RetrieveTrigger(RedisJobStoreSchema.TriggerKey(triggerHashKey)); + var trigger = await RetrieveTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey)); - ResumeTrigger(trigger.Key); + await ResumeTriggerAsync(trigger.Key); - if(!resumedTriggerGroups.Contains(trigger.Key.Group)) { + if(!resumedTriggerGroups.Contains(trigger.Key.Group)) resumedTriggerGroups.Add(trigger.Key.Group); - } } } else { - foreach (var triggerGroupSetKy in Db.SetMembersAsync(RedisJobStoreSchema.TriggerGroupsSetKey()).Result) + foreach (var triggerGroupSetKy in await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey())) { - if (matcher.CompareWithOperator.Evaluate(RedisJobStoreSchema.TriggerGroup(triggerGroupSetKy), - matcher.CompareToValue)) - { - resumedTriggerGroups.AddRange(ResumeTriggers(GroupMatcher.GroupEquals(RedisJobStoreSchema.TriggerGroup(triggerGroupSetKy)))); - } + if (matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.TriggerGroup(triggerGroupSetKy), matcher.CompareToValue)) + resumedTriggerGroups.AddRange(await ResumeTriggersAsync(GroupMatcher.GroupEquals(redisJobStoreSchema.TriggerGroup(triggerGroupSetKy)))); } } - return resumedTriggerGroups; } /// /// Pause the with the given key. /// - public override void PauseTrigger(TriggerKey triggerKey) + public override async Task PauseTriggerAsync(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); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerExistsResult = await db.KeyExistsAsync(triggerHashKey); + var completedScoreResult = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Completed), triggerHashKey); + var nextFireTimeResult = await db.HashGetAsync(triggerHashKey, RedisJobStoreSchema.NextFireTime); + var blockedScoreResult = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked), triggerHashKey); - if (!triggerExistsResult) - { - return; - } - if (completedScoreResult.HasValue) - { + if (!triggerExistsResult || 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); - } + var newTriggerState = blockedScoreResult.HasValue + ? RedisTriggerState.PausedBlocked + : RedisTriggerState.Paused; + + await SetTriggerStateAsync(newTriggerState, nextFireTime, triggerHashKey); } /// @@ -578,102 +497,92 @@ public override void PauseTrigger(TriggerKey triggerKey) /// state. Preference is to return an empty list if none of the triggers /// could be fired. /// - public override IList TriggersFired(IList triggers) + public override async Task> TriggersFiredAsync(IReadOnlyCollection triggers) { var result = new List(); foreach (var trigger in triggers) { - var triggerHashKey = RedisJobStoreSchema.TriggerHashkey(trigger.Key); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(trigger.Key); - var triggerExistResult = Db.KeyExists(triggerHashKey); - var triggerAcquiredResult = - Db.SortedSetScore(RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired), - triggerHashKey); + var triggerExistResult = await db.KeyExistsAsync(triggerHashKey); + var triggerAcquiredResult = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired), triggerHashKey); if (triggerExistResult == false) { - Logger.WarnFormat("Trigger {0} does not exist", triggerHashKey); + Logger.LogWarning("Trigger {0} does not exist", triggerHashKey); continue; } if (!triggerAcquiredResult.HasValue) { - Logger.WarnFormat("Trigger {0} was not acquired", triggerHashKey); + Logger.LogWarning("Trigger {0} was not acquired", triggerHashKey); continue; } ICalendar calendar = null; - string calendarname = trigger.CalendarName; + var calendarname = trigger.CalendarName; if (!string.IsNullOrEmpty(calendarname)) { - calendar = this.RetrieveCalendar(calendarname); + calendar = await RetrieveCalendarAsync(calendarname); if (calendar == null) - { continue; - } } var previousFireTime = trigger.GetPreviousFireTimeUtc(); trigger.Triggered(calendar); - var job = this.RetrieveJob(trigger.JobKey); + var job = await RetrieveJobAsync(trigger.JobKey); + + if (job == null) + { + Logger.LogWarning("Could not find implementation for job {0}", trigger.JobKey); + continue; + } - var triggerFireBundle = new TriggerFiredBundle(job, trigger, calendar, false, DateTimeOffset.UtcNow, - previousFireTime, previousFireTime, trigger.GetNextFireTimeUtc()); + 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); + var jobHasKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); + var jobTriggerSetKey = redisJobStoreSchema.JobTriggersSetKey(job.Key); - foreach (var nonConcurrentTriggerHashKey in this.Db.SetMembers(jobTriggerSetKey)) + foreach (var nonConcurrentTriggerHashKey in await db.SetMembersAsync(jobTriggerSetKey)) { - var score = - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), - nonConcurrentTriggerHashKey); + var score = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), nonConcurrentTriggerHashKey); if (score.HasValue) - { - this.SetTriggerState(RedisTriggerState.Blocked, score.Value, nonConcurrentTriggerHashKey); - } + await SetTriggerStateAsync(RedisTriggerState.Blocked, score.Value, nonConcurrentTriggerHashKey); else { - score = this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused), - nonConcurrentTriggerHashKey); + score = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused), nonConcurrentTriggerHashKey); if (score.HasValue) - { - this.SetTriggerState(RedisTriggerState.PausedBlocked, score.Value, nonConcurrentTriggerHashKey); - } + await SetTriggerStateAsync(RedisTriggerState.PausedBlocked, score.Value, nonConcurrentTriggerHashKey); } } - - Db.SetAdd(this.RedisJobStoreSchema.JobBlockedKey(job.Key), this.SchedulerInstanceId); - - Db.SetAdd(this.RedisJobStoreSchema.BlockedJobsSet(), jobHasKey); + await db.SetAddAsync(redisJobStoreSchema.JobBlockedKey(job.Key), schedulerInstanceId); + await db.SetAddAsync(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); - } - + if (nextFireTimeUtc != null) + { + var nextFireTime = nextFireTimeUtc.Value; + await db.HashSetAsync(triggerHashKey, RedisJobStoreSchema.NextFireTime, nextFireTime.DateTime.ToUnixTimeMilliSeconds()); + await SetTriggerStateAsync(RedisTriggerState.Waiting, nextFireTime.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); + } else { - this.Db.HashSet(triggerHashKey, RedisJobStoreSchema.NextFireTime, ""); - this.UnsetTriggerState(triggerHashKey); + await db.HashSetAsync(triggerHashKey, RedisJobStoreSchema.NextFireTime, ""); + await UnsetTriggerStateAsync(triggerHashKey); } result.Add(new TriggerFiredResult(triggerFireBundle)); - } return result; @@ -686,161 +595,137 @@ public override IList TriggersFired(IList /// in the given should be updated if the /// is stateful. /// - public override void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail jobDetail, SchedulerInstruction triggerInstCode) + public override async Task TriggeredJobCompleteAsync(IOperableTrigger trigger, IJobDetail jobDetail, SchedulerInstruction triggerInstCode) { - var jobHashKey = this.RedisJobStoreSchema.JobHashKey(jobDetail.Key); + var jobHashKey = redisJobStoreSchema.JobHashKey(jobDetail.Key); + var jobDataMapHashKey = redisJobStoreSchema.JobDataMapHashKey(jobDetail.Key); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(trigger.Key); - var jobDataMapHashKey = this.RedisJobStoreSchema.JobDataMapHashKey(jobDetail.Key); - - var triggerHashKey = this.RedisJobStoreSchema.TriggerHashkey(trigger.Key); - - if (this.Db.KeyExists(jobHashKey)) + if (await db.KeyExistsAsync(jobHashKey)) { - Logger.InfoFormat("{0} - Job has completed", jobHashKey); + Logger.LogInformation("{0} - Job has completed", jobHashKey); if (jobDetail.PersistJobDataAfterExecution) { var jobDataMap = jobDetail.JobDataMap; - Db.KeyDelete(jobDataMapHashKey); + await db.KeyDeleteAsync(jobDataMapHashKey); if (jobDataMap != null && !jobDataMap.IsEmpty) - { - Db.HashSet(jobDataMapHashKey, ConvertToHashEntries(jobDataMap)); - } - + await db.HashSetAsync(jobDataMapHashKey, ConvertToHashEntries(jobDataMap)); } if (jobDetail.ConcurrentExecutionDisallowed) { + await db.SetRemoveAsync(redisJobStoreSchema.BlockedJobsSet(), jobHashKey); + await db.KeyDeleteAsync(redisJobStoreSchema.JobBlockedKey(jobDetail.Key)); - Db.SetRemove(this.RedisJobStoreSchema.BlockedJobsSet(), jobHashKey); - - Db.KeyDelete(this.RedisJobStoreSchema.JobBlockedKey(jobDetail.Key)); + var jobTriggersSetKey = redisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); - var jobTriggersSetKey = this.RedisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); - - foreach (var nonConcurrentTriggerHashKey in this.Db.SetMembers(jobTriggersSetKey)) + foreach (var nonConcurrentTriggerHashKey in await db.SetMembersAsync(jobTriggersSetKey)) { - var score = - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked), - nonConcurrentTriggerHashKey); + var score = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked), nonConcurrentTriggerHashKey); if (score.HasValue) - { - this.SetTriggerState(RedisTriggerState.Paused, score.Value, nonConcurrentTriggerHashKey); - } + await SetTriggerStateAsync(RedisTriggerState.Paused, score.Value, nonConcurrentTriggerHashKey); else { - score = - this.Db.SortedSetScoreAsync( - this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked), - nonConcurrentTriggerHashKey).Result; + score = await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked), nonConcurrentTriggerHashKey); if (score.HasValue) - { - this.SetTriggerState(RedisTriggerState.Paused, score.Value, nonConcurrentTriggerHashKey); - } + await SetTriggerStateAsync(RedisTriggerState.Paused, score.Value, nonConcurrentTriggerHashKey); } } - this.SchedulerSignaler.SignalSchedulingChange(null); + signaler.SignalSchedulingChange(null); } - } else - { - this.Db.SetRemove(this.RedisJobStoreSchema.BlockedJobsSet(), jobHashKey); - } + await db.SetRemoveAsync(redisJobStoreSchema.BlockedJobsSet(), jobHashKey); - if (this.Db.KeyExists(triggerHashKey)) + if (await db.KeyExistsAsync(triggerHashKey)) { if (triggerInstCode == SchedulerInstruction.DeleteTrigger) { if (trigger.GetNextFireTimeUtc().HasValue == false) { - if (string.IsNullOrEmpty(this.Db.HashGet(triggerHashKey, RedisJobStoreSchema.NextFireTime))) - { - RemoveTrigger(trigger.Key); - } + if (string.IsNullOrEmpty(await db.HashGetAsync(triggerHashKey, RedisJobStoreSchema.NextFireTime))) + await RemoveTriggerAsync(trigger.Key); } else { - this.RemoveTrigger(trigger.Key); - this.SchedulerSignaler.SignalSchedulingChange(null); + await RemoveTriggerAsync(trigger.Key); + signaler.SignalSchedulingChange(null); } } else if (triggerInstCode == SchedulerInstruction.SetTriggerComplete) { - this.SetTriggerState(RedisTriggerState.Completed, DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); - this.SchedulerSignaler.SignalSchedulingChange(null); + await SetTriggerStateAsync(RedisTriggerState.Completed, DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(), triggerHashKey); + signaler.SignalSchedulingChange(null); } else if (triggerInstCode == SchedulerInstruction.SetTriggerError) { - double score = trigger.GetNextFireTimeUtc().HasValue - ? trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds() : 0; - this.SetTriggerState(RedisTriggerState.Error, score, triggerHashKey); - this.SchedulerSignaler.SignalSchedulingChange(null); + var score = trigger.GetNextFireTimeUtc()?.DateTime.ToUnixTimeMilliSeconds() ?? 0; + await SetTriggerStateAsync(RedisTriggerState.Error, score, triggerHashKey); + signaler.SignalSchedulingChange(null); } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersError) { - var jobTriggersSetKey = this.RedisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); + var jobTriggersSetKey = redisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); - foreach (var errorTriggerHashKey in this.Db.SetMembersAsync(jobTriggersSetKey).Result) + foreach (var errorTriggerHashKey in await db.SetMembersAsync(jobTriggersSetKey)) { - var nextFireTime = this.Db.HashGetAsync(errorTriggerHashKey.ToString(), RedisJobStoreSchema.NextFireTime).Result; + var nextFireTime = await db.HashGetAsync(errorTriggerHashKey.ToString(), RedisJobStoreSchema.NextFireTime); var score = string.IsNullOrEmpty(nextFireTime) ? 0 : double.Parse(nextFireTime); - this.SetTriggerState(RedisTriggerState.Error, score, errorTriggerHashKey); + await SetTriggerStateAsync(RedisTriggerState.Error, score, errorTriggerHashKey); } - this.SchedulerSignaler.SignalSchedulingChange(null); + signaler.SignalSchedulingChange(null); } else if (triggerInstCode == SchedulerInstruction.SetAllJobTriggersComplete) { - var jobTriggerSetKey = this.RedisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); + var jobTriggerSetKey = redisJobStoreSchema.JobTriggersSetKey(jobDetail.Key); - foreach (var completedTriggerHashKey in this.Db.SetMembersAsync(jobTriggerSetKey).Result) - { - this.SetTriggerState(RedisTriggerState.Completed, DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(), - completedTriggerHashKey); - } + foreach (var completedTriggerHashKey in await db.SetMembersAsync(jobTriggerSetKey)) + await SetTriggerStateAsync(RedisTriggerState.Completed, DateTimeOffset.UtcNow.DateTime.ToUnixTimeMilliSeconds(), completedTriggerHashKey); - this.SchedulerSignaler.SignalSchedulingChange(null); + signaler.SignalSchedulingChange(null); } } } /// - /// Get the names of all of the s that - /// have the given group name. + /// Get the names of all of the s that have the given group name. /// - /// If there are no jobs in the given group name, the result should be a - /// zero-length array (not ). + /// If there are no jobs in the given group name, the result should be a zero-length array (not ). /// /// /// /// - public override global::Quartz.Collection.ISet JobKeys(GroupMatcher matcher) + public override async Task> JobKeysAsync(GroupMatcher matcher) { - var jobKeys = new global::Quartz.Collection.HashSet(); + var jobKeys = new HashSet(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var jobGroupSetKey = this.RedisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); - var jobHashKeys = this.Db.SetMembers(jobGroupSetKey); + var jobGroupSetKey = redisJobStoreSchema.JobGroupSetKey(matcher.CompareToValue); + var jobHashKeys = await db.SetMembersAsync(jobGroupSetKey); + if (jobHashKeys != null) { foreach (var jobHashKey in jobHashKeys) - { - jobKeys.Add(this.RedisJobStoreSchema.JobKey(jobHashKey)); - } + jobKeys.Add(redisJobStoreSchema.JobKey(jobHashKey)); } } else { - var jobGroupSets = this.Db.SetMembers(this.RedisJobStoreSchema.JobGroupsSetKey()); + var allJobGroups = await db.SetMembersAsync(redisJobStoreSchema.JobGroupsSetKey()); + var filteredJobGroups = allJobGroups.Where(jobGroupSet => matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.JobGroup(jobGroupSet), matcher.CompareToValue)); - var jobGroupsResult = (from groupSet in jobGroupSets where matcher.CompareWithOperator.Evaluate(this.RedisJobStoreSchema.JobGroup(groupSet), matcher.CompareToValue) select Db.SetMembers(groupSet.ToString())).ToList(); - - foreach (var jobHashKey in jobGroupsResult.Where(jobHashKeys => jobHashKeys != null).SelectMany(jobHashKeys => jobHashKeys)) + foreach (var jobGroup in filteredJobGroups) { - jobKeys.Add(this.RedisJobStoreSchema.JobKey(jobHashKey)); + var jobs = await db.SetMembersAsync(jobGroup.ToString()); + if (jobs != null) + { + foreach (var jobHashKey in jobs) + jobKeys.Add(redisJobStoreSchema.JobKey(jobHashKey)); + } } } @@ -848,43 +733,36 @@ public override void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail j } /// - /// Get the names of all of the s - /// that have the given group name. + /// Get the names of all of the s that have the given group name. /// - /// If there are no triggers in the given group name, the result should be a - /// zero-length array (not ). + /// If there are no triggers in the given group name, the result should be a zero-length array (not ). /// /// - public override global::Quartz.Collection.ISet TriggerKeys(GroupMatcher matcher) + public override async Task> TriggerKeysAsync(GroupMatcher matcher) { - var triggerKeys = new global::Quartz.Collection.HashSet(); + var triggerKeys = new HashSet(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var triggerGroupSetKey = - this.RedisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); - - var triggers = this.Db.SetMembers(triggerGroupSetKey); + var triggerGroupSetKey = redisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); + var triggers = await db.SetMembersAsync(triggerGroupSetKey); foreach (var trigger in triggers) - { - triggerKeys.Add(this.RedisJobStoreSchema.TriggerKey(trigger)); - } + triggerKeys.Add(redisJobStoreSchema.TriggerKey(trigger)); } else { - var triggerGroupSets = this.Db.SetMembersAsync(this.RedisJobStoreSchema.TriggerGroupsSetKey()).Result; - var triggerGroupsResult = (from groupSet in triggerGroupSets where matcher.CompareWithOperator.Evaluate(this.RedisJobStoreSchema.TriggerGroup(groupSet), matcher.CompareToValue) select Db.SetMembers(groupSet.ToString())).ToList(); + var allTriggerGroups = await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey()); + var filteredGroups = allTriggerGroups.Where(groupSet => matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.JobGroup(groupSet), matcher.CompareToValue)); - foreach (var triggerHashKeys in triggerGroupsResult) + foreach (var triggerGroup in filteredGroups) { - if (triggerHashKeys != null) + var triggers = await db.SetMembersAsync(triggerGroup.ToString()); + if (triggers != null) { - foreach (var triggerHashKey in triggerHashKeys) - { - triggerKeys.Add(this.RedisJobStoreSchema.TriggerKey(triggerHashKey)); - } + foreach (var triggerHashKey in triggers) + triggerKeys.Add(redisJobStoreSchema.TriggerKey(triggerHashKey)); } } } @@ -896,44 +774,28 @@ public override void TriggeredJobComplete(IOperableTrigger trigger, IJobDetail j /// Get the current state of the identified . /// /// - public override TriggerState GetTriggerState(TriggerKey triggerKey) + public override async Task GetTriggerStateAsync(TriggerKey triggerKey) { - var triggerHashKey = this.RedisJobStoreSchema.TriggerHashkey(triggerKey); + var triggerHashKey = redisJobStoreSchema.TriggerHashkey(triggerKey); - if ( - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused), - triggerHashKey) != null || - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked), - triggerHashKey) != null) - { + if (await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Paused), triggerHashKey) != null || + await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.PausedBlocked), triggerHashKey) != null) return TriggerState.Paused; - } - if ( - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked), triggerHashKey) != null) - { + + if (await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Blocked), triggerHashKey) != null) return TriggerState.Blocked; - } - if ( - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), - triggerHashKey) != null || this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired),triggerHashKey) !=null) - { + + if (await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Waiting), triggerHashKey) != null || + await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Acquired),triggerHashKey) !=null) return TriggerState.Normal; - } - if ( - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Completed), - triggerHashKey) != null) - { + + if (await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Completed), triggerHashKey) != null) return TriggerState.Complete; - } - if ( - this.Db.SortedSetScore(this.RedisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Error), triggerHashKey) - != null) - { + + if (await db.SortedSetScoreAsync(redisJobStoreSchema.TriggerStateSetKey(RedisTriggerState.Error), triggerHashKey) != null) return TriggerState.Error; - } return TriggerState.None; - } /// @@ -945,44 +807,43 @@ public override TriggerState GetTriggerState(TriggerKey triggerKey) /// pause on any new triggers that are added to the group while the group is /// paused. /// - public override IList PauseTriggers(GroupMatcher matcher) + public override async Task> PauseTriggersAsync(GroupMatcher matcher) { var pausedTriggerGroups = new List(); if (matcher.CompareWithOperator.Equals(StringOperator.Equality)) { - var triggerGroupSetKey = this.RedisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); - var addResult = this.Db.SetAdd(this.RedisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroupSetKey); + var triggerGroupSetKey = redisJobStoreSchema.TriggerGroupSetKey(matcher.CompareToValue); + var addResult = await db.SetAddAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroupSetKey); if (addResult) { - foreach (var triggerHashKey in this.Db.SetMembers(triggerGroupSetKey)) - { - this.PauseTrigger(this.RedisJobStoreSchema.TriggerKey(triggerHashKey)); - } + foreach (var triggerHashKey in await db.SetMembersAsync(triggerGroupSetKey)) + await PauseTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey)); - pausedTriggerGroups.Add(this.RedisJobStoreSchema.TriggerGroup(triggerGroupSetKey)); + pausedTriggerGroups.Add(redisJobStoreSchema.TriggerGroup(triggerGroupSetKey)); } } else { - var allTriggerGroups = this.Db.SetMembers(this.RedisJobStoreSchema.TriggerGroupsSetKey()); + var allTriggerGroups = await db.SetMembersAsync(redisJobStoreSchema.TriggerGroupsSetKey()); + var filteredTriggerGroups = allTriggerGroups.Where(groupHashKey => matcher.CompareWithOperator.Evaluate(redisJobStoreSchema.TriggerGroup(groupHashKey), matcher.CompareToValue)); - var triggerGroupsResult = allTriggerGroups.Where(groupHashKey => matcher.CompareWithOperator.Evaluate(this.RedisJobStoreSchema.TriggerGroup(groupHashKey), matcher.CompareToValue)).ToDictionary(groupHashKey => groupHashKey, groupHashKey => Db.SetMembers(groupHashKey.ToString())); - - foreach (var triggerGroup in triggerGroupsResult) + foreach (var triggerGroup in filteredTriggerGroups) { - var addResult = this.Db.SetAdd(this.RedisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroup.Key); + var triggers = await db.SetMembersAsync(triggerGroup.ToString()); + + var addResult = await db.SetAddAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey(), triggerGroup); if (addResult) { - foreach (var triggerHashKey in triggerGroup.Value) + if (triggers != null) { - this.PauseTrigger(this.RedisJobStoreSchema.TriggerKey(triggerHashKey)); + foreach (var triggerHashKey in triggers) + await PauseTriggerAsync(redisJobStoreSchema.TriggerKey(triggerHashKey)); } - pausedTriggerGroups.Add(this.RedisJobStoreSchema.TriggerGroup(triggerGroup.Key)); + pausedTriggerGroups.Add(redisJobStoreSchema.TriggerGroup(triggerGroup)); } } - } return pausedTriggerGroups; @@ -994,37 +855,25 @@ public override IList PauseTriggers(GroupMatcher matcher) /// else set the trigger to the normal state (waiting), conver the nextfiretime into UTC milliseconds, so it could be stored as score in the sorted set. /// /// ITrigger - private void UpdateTriggerState(ITrigger trigger) + async Task UpdateTriggerStateAsync(ITrigger trigger) { - var triggerPausedResult = - this.Db.SetContains(this.RedisJobStoreSchema.PausedTriggerGroupsSetKey(), - this.RedisJobStoreSchema.TriggerGroupSetKey(trigger.Key.Group)); - var jobPausedResult = this.Db.SetContains(this.RedisJobStoreSchema.PausedJobGroupsSetKey(), - this.RedisJobStoreSchema.JobGroupSetKey(trigger.JobKey.Group)); + var triggerPausedResult = await db.SetContainsAsync(redisJobStoreSchema.PausedTriggerGroupsSetKey(), redisJobStoreSchema.TriggerGroupSetKey(trigger.Key.Group)); + var jobPausedResult = await db.SetContainsAsync(redisJobStoreSchema.PausedJobGroupsSetKey(), redisJobStoreSchema.JobGroupSetKey(trigger.JobKey.Group)); if (triggerPausedResult || jobPausedResult) { - double nextFireTime = trigger.GetNextFireTimeUtc().HasValue - ? trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds() : -1; + var nextFireTime = trigger.GetNextFireTimeUtc()?.DateTime.ToUnixTimeMilliSeconds() ?? -1; - var jobHashKey = this.RedisJobStoreSchema.JobHashKey(trigger.JobKey); + var jobHashKey = redisJobStoreSchema.JobHashKey(trigger.JobKey); - if (this.Db.SetContains(this.RedisJobStoreSchema.BlockedJobsSet(), jobHashKey)) - { - this.SetTriggerState(RedisTriggerState.PausedBlocked, - nextFireTime, this.RedisJobStoreSchema.TriggerHashkey(trigger.Key)); - } - else - { - this.SetTriggerState(RedisTriggerState.Paused, - nextFireTime, this.RedisJobStoreSchema.TriggerHashkey(trigger.Key)); - } + var newTriggerState = await db.SetContainsAsync(redisJobStoreSchema.BlockedJobsSet(), jobHashKey) + ? RedisTriggerState.PausedBlocked + : RedisTriggerState.Paused; + + await SetTriggerStateAsync(newTriggerState, nextFireTime, redisJobStoreSchema.TriggerHashkey(trigger.Key)); } else if (trigger.GetNextFireTimeUtc().HasValue) - { - this.SetTriggerState(RedisTriggerState.Waiting, - trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds(), this.RedisJobStoreSchema.TriggerHashkey(trigger.Key)); - } + await SetTriggerStateAsync(RedisTriggerState.Waiting, trigger.GetNextFireTimeUtc().Value.DateTime.ToUnixTimeMilliSeconds(), redisJobStoreSchema.TriggerHashkey(trigger.Key)); } #endregion } diff --git a/QuartzRedisJobStore.JobStore/app.config b/QuartzRedisJobStore.JobStore/app.config new file mode 100644 index 0000000..d9c836a --- /dev/null +++ b/QuartzRedisJobStore.JobStore/app.config @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/QuartzRedisJobStore.JobStore/packages.config b/QuartzRedisJobStore.JobStore/packages.config index 0bec4dd..b1a1331 100644 --- a/QuartzRedisJobStore.JobStore/packages.config +++ b/QuartzRedisJobStore.JobStore/packages.config @@ -2,8 +2,28 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/QuartzRedisJobStore.UnitTest/App.config b/QuartzRedisJobStore.UnitTest/App.config index 9981d04..28c2e6b 100644 --- a/QuartzRedisJobStore.UnitTest/App.config +++ b/QuartzRedisJobStore.UnitTest/App.config @@ -1,4 +1,4 @@ - + @@ -7,10 +7,76 @@ - + + - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/QuartzRedisJobStore.UnitTest/BaseFixture.cs b/QuartzRedisJobStore.UnitTest/BaseFixture.cs index 65a2739..700893c 100644 --- a/QuartzRedisJobStore.UnitTest/BaseFixture.cs +++ b/QuartzRedisJobStore.UnitTest/BaseFixture.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Configuration; +using System.Linq; +using System.Net; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Newtonsoft.Json; @@ -17,7 +20,8 @@ namespace QuartzRedisJobStore.UnitTest /// /// base test fixture /// - public abstract class BaseFixture { + public abstract class BaseFixture + { /// /// RedisJobStore /// @@ -30,7 +34,7 @@ public abstract class BaseFixture { /// /// KeyPrefix /// - private const string KeyPrefix = "UnitTest1"; + private const string KeyPrefix = "QuartzRedisJobStore:UnitTest:"; /// /// IDatabase /// @@ -49,27 +53,36 @@ public abstract class BaseFixture { /// /// constructor /// - protected BaseFixture() { - InitializeJobStore(); + protected BaseFixture() + { + InitializeJobStore().Wait(); } /// /// initialize the job store /// - private static void InitializeJobStore() + static async Task InitializeJobStore() { + var redisConfiguration = ConfigurationOptions.Parse(ConfigurationManager.AppSettings["RedisConfiguration"]); + + var uri = new Uri($"redis://{redisConfiguration.EndPoints.FirstOrDefault()}", UriKind.Absolute); + JobStore = new RedisJobStore { - RedisConfiguration = ConfigurationManager.AppSettings["RedisConfiguration"], + Host = uri.Host, + Port = uri.Port, + Password = redisConfiguration.Password, + Ssl = redisConfiguration.Ssl, + Database = redisConfiguration.DefaultDatabase ?? 0, KeyPrefix = KeyPrefix, InstanceId = "UnitTestInstanceId" }; MockedSignaler = new Mock(); - MockedSignaler.Setup(x => x.NotifySchedulerListenersJobDeleted(null)); - MockedSignaler.Setup(x => x.SignalSchedulingChange(null)); - JobStore.Initialize(null, MockedSignaler.Object); + MockedSignaler.Setup(x => x.NotifySchedulerListenersJobDeleted(null, default)); + MockedSignaler.Setup(x => x.SignalSchedulingChange(null, default)); + await JobStore.Initialize(null, MockedSignaler.Object); Schema = new RedisJobStoreSchema(KeyPrefix); - Db = ConnectionMultiplexer.Connect(JobStore.RedisConfiguration).GetDatabase(); + Db = (await ConnectionMultiplexer.ConnectAsync(redisConfiguration)).GetDatabase(redisConfiguration.DefaultDatabase ?? 0); } /// @@ -77,6 +90,7 @@ private static void InitializeJobStore() /// public static void CleanUp() { + /* var endpoints = Db?.Multiplexer.GetEndPoints(); if (endpoints != null) @@ -86,10 +100,9 @@ public static void CleanUp() Db?.Multiplexer.GetServer(endpoint).FlushDatabase(); } } + */ } - - /// /// create a dummy job /// @@ -127,16 +140,16 @@ protected static IOperableTrigger CreateTrigger(string name, string group, JobKe .WithDescription("TriggerTesting") .Build(); - var abstractTrigger = (AbstractTrigger)trigger; - - if (abstractTrigger != null) + if ((trigger is AbstractTrigger abstractTrigger) && !string.IsNullOrEmpty(calendarName)) { var calendar = new WeeklyCalendar { DaysExcluded = null }; abstractTrigger.ComputeFirstFireTimeUtc(calendar); abstractTrigger.CalendarName = calendarName; + + return abstractTrigger; } - return abstractTrigger ?? (IOperableTrigger)trigger; + return (IOperableTrigger)trigger; } /// @@ -144,11 +157,12 @@ protected static IOperableTrigger CreateTrigger(string name, string group, JobKe /// /// Description /// ICalendar - protected static ICalendar CreateCalendar(string description="week days only") { + protected static ICalendar CreateCalendar(string description = "week days only") + { var calendar = new WeeklyCalendar(); calendar.SetDayExcluded(DayOfWeek.Saturday, true); - calendar.SetDayExcluded(DayOfWeek.Sunday,true); + calendar.SetDayExcluded(DayOfWeek.Sunday, true); calendar.Description = description; @@ -160,10 +174,11 @@ protected static ICalendar CreateCalendar(string description="week days only") { /// /// IJobDetail /// Triggers - protected void StoreJobAndTriggers(IJobDetail job,global::Quartz.Collection.ISet triggers) { - var dictionary = new Dictionary> {{job, triggers}}; + protected async Task StoreJobAndTriggers(IJobDetail job, IReadOnlyCollection triggers) + { + var dictionary = new Dictionary> { { job, triggers } }; - JobStore.StoreJobsAndTriggers(dictionary,true); + await JobStore.StoreJobsAndTriggers(dictionary, true); } /// @@ -175,11 +190,11 @@ protected void StoreJobAndTriggers(IJobDetail job,global::Quartz.Collection.ISet /// number of triggers per group /// unix cron expression /// jobs and triggers - protected static IDictionary> CreateJobsAndTriggers(int jobGroups, int jobsPerGroup, int triggerGroupsPerJob, + protected static IReadOnlyDictionary> CreateJobsAndTriggers(int jobGroups, int jobsPerGroup, int triggerGroupsPerJob, int triggersPerGroup, string cronExpression = "") { - var jobsAndTriggers = new Dictionary>(); + var jobsAndTriggers = new Dictionary>(); for (int g = 0; g < jobGroups; g++) { @@ -188,7 +203,7 @@ protected void StoreJobAndTriggers(IJobDetail job,global::Quartz.Collection.ISet { var jobName = "jobName_" + j; var job = CreateJob(jobName, jobGroup); - var triggerSet = new global::Quartz.Collection.HashSet(); + var triggerSet = new HashSet(); for (int tg = 0; tg < triggerGroupsPerJob; tg++) { var triggerGroup = "triggerGroup_" + tg + "_" + j + g; @@ -202,7 +217,7 @@ protected void StoreJobAndTriggers(IJobDetail job,global::Quartz.Collection.ISet } else { - triggerSet.Add(CreateTrigger(triggerName, triggerGroup, job.Key, cronExpression)); + triggerSet.Add(CreateTrigger(triggerName, triggerGroup, job.Key, cronExpression, "testCalendar")); } } } diff --git a/QuartzRedisJobStore.UnitTest/CalendarFixture.cs b/QuartzRedisJobStore.UnitTest/CalendarFixture.cs index 83e07f6..1412e6c 100644 --- a/QuartzRedisJobStore.UnitTest/CalendarFixture.cs +++ b/QuartzRedisJobStore.UnitTest/CalendarFixture.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json; using Quartz; @@ -25,7 +26,7 @@ public class CalendarFixture : BaseFixture public void ClearAllJobStoreData() { System.Diagnostics.Debug.Write("here"); - JobStore?.ClearAllSchedulingData(); + JobStore?.ClearAllSchedulingData().Wait(); System.Diagnostics.Debug.Write(counter++); } @@ -39,14 +40,15 @@ public static void ClassCleanup() /// store a calendar /// [TestMethod] - public void StoreCalendarSuccesfully() { + public async Task StoreCalendarSuccesfully() + { //arrange var calendar = CreateCalendar(); var calendarHashKey = Schema.CalendarHashKey(CalendarName); //act - JobStore.StoreCalendar(CalendarName,calendar,false,false); - var calendarProperties = Db.HashGetAll(calendarHashKey); + await JobStore.StoreCalendar(CalendarName, calendar, false, false); + var calendarProperties = await Db.HashGetAllAsync(calendarHashKey); var serializedCalendar = (from hashEntry in calendarProperties where hashEntry.Name == RedisJobStoreSchema.CalendarSerialized select hashEntry.Value).FirstOrDefault(); @@ -55,7 +57,7 @@ public void StoreCalendarSuccesfully() { //assert Assert.IsNotNull(retrievedCalendar); - Assert.AreEqual(retrievedCalendar.Description,calendar.Description); + Assert.AreEqual(calendar.Description, retrievedCalendar.Description); } @@ -64,18 +66,23 @@ public void StoreCalendarSuccesfully() { /// the original one will not be overriden. /// [TestMethod] - public void StoreCalendar_WithoutReplacingExisting_NoOverride() { + public async Task StoreCalendar_WithoutReplacingExisting_NoOverride() + { //arrange var calendar1 = CreateCalendar(); var calendar2 = CreateCalendar("another week days only"); //act - JobStore.StoreCalendar(CalendarName,calendar1,false,false); - JobStore.StoreCalendar(CalendarName,calendar2,false,false); - var retrievedCalendar = JobStore.RetrieveCalendar(CalendarName); + await JobStore.StoreCalendar(CalendarName, calendar1, false, false); + try + { + await JobStore.StoreCalendar(CalendarName, calendar2, false, false); + } + catch { } + var retrievedCalendar = await JobStore.RetrieveCalendar(CalendarName); //assert - Assert.AreEqual(retrievedCalendar.Description,calendar1.Description); + Assert.AreEqual(retrievedCalendar.Description, calendar1.Description); } /// @@ -83,16 +90,16 @@ public void StoreCalendar_WithoutReplacingExisting_NoOverride() { /// the original one will be overriden. /// [TestMethod] - public void StoreCalendar_WithReplacingExisting_OverrideSuccessfully() + public async Task StoreCalendar_WithReplacingExisting_OverrideSuccessfully() { //arrange var calendar1 = CreateCalendar(); var calendar2 = CreateCalendar("another week days only"); //act - JobStore.StoreCalendar(CalendarName, calendar1, false, false); - JobStore.StoreCalendar(CalendarName, calendar2, true, false); - var retrievedCalendar = JobStore.RetrieveCalendar(CalendarName); + await JobStore.StoreCalendar(CalendarName, calendar1, false, false); + await JobStore.StoreCalendar(CalendarName, calendar2, true, false); + var retrievedCalendar = await JobStore.RetrieveCalendar(CalendarName); //assert Assert.AreEqual(retrievedCalendar.Description, calendar2.Description); @@ -102,32 +109,34 @@ public void StoreCalendar_WithReplacingExisting_OverrideSuccessfully() /// retrieve a calendar /// [TestMethod] - public void RetrieveCalendarSuccessfully() { + public async Task RetrieveCalendarSuccessfully() + { //arrange var calendar = CreateCalendar(); - JobStore.StoreCalendar(CalendarName, calendar, true, false); + await JobStore.StoreCalendar(CalendarName, calendar, true, false); //act - var retrievedCalendar = JobStore.RetrieveCalendar(CalendarName); + var retrievedCalendar = await JobStore.RetrieveCalendar(CalendarName); //assert - Assert.AreEqual(calendar.Description,retrievedCalendar.Description); + Assert.AreEqual(calendar.Description, retrievedCalendar.Description); var utcNow = new DateTimeOffset(DateTime.UtcNow); - Assert.AreEqual(calendar.GetNextIncludedTimeUtc(utcNow),retrievedCalendar.GetNextIncludedTimeUtc(utcNow)); + Assert.AreEqual(calendar.GetNextIncludedTimeUtc(utcNow), retrievedCalendar.GetNextIncludedTimeUtc(utcNow)); } /// /// get total number of calendars in the store /// [TestMethod] - public void GetNumberOfCalendarSuccessfully() { + public async Task GetNumberOfCalendarSuccessfully() + { //arrange - JobStore.StoreCalendar("cal1", CreateCalendar(), true, false); - JobStore.StoreCalendar("cal2", CreateCalendar(), true, false); - JobStore.StoreCalendar("cal3", CreateCalendar(), true, false); + await JobStore.StoreCalendar("cal1", CreateCalendar(), true, false); + await JobStore.StoreCalendar("cal2", CreateCalendar(), true, false); + await JobStore.StoreCalendar("cal3", CreateCalendar(), true, false); //act - var numbers = JobStore.GetNumberOfCalendars(); + var numbers = await JobStore.GetNumberOfCalendars(); //assert Assert.IsTrue(numbers == 3); @@ -137,29 +146,31 @@ public void GetNumberOfCalendarSuccessfully() { /// remove a calendar /// [TestMethod] - public void RemoveCalendarSuccessfully() { + public async Task RemoveCalendarSuccessfully() + { //arrange - JobStore.StoreCalendar(CalendarName,CreateCalendar(),false,false); - + await JobStore.StoreCalendar(CalendarName, CreateCalendar(), false, false); + //act - var result = JobStore.RemoveCalendar(CalendarName); + var result = await JobStore.RemoveCalendar(CalendarName); //assert Assert.IsTrue(result); - Assert.IsNull(JobStore.RetrieveCalendar(CalendarName)); + Assert.IsNull(await JobStore.RetrieveCalendar(CalendarName)); } /// /// Get all the calendar names in the store /// [TestMethod] - public void GetCalendarNamesSuccessfully() { + public async Task GetCalendarNamesSuccessfully() + { //arrange - JobStore.StoreCalendar("cal1",CreateCalendar(),false,false); - JobStore.StoreCalendar("cal2", CreateCalendar(), false, false); + await JobStore.StoreCalendar("cal1", CreateCalendar(), false, false); + await JobStore.StoreCalendar("cal2", CreateCalendar(), false, false); //act - var result = JobStore.GetCalendarNames(); + var result = await JobStore.GetCalendarNames(); //assert Assert.IsTrue(result.Count == 2); @@ -169,15 +180,18 @@ public void GetCalendarNamesSuccessfully() { /// Calendar could not be removed then there are triggers associated with it. /// [TestMethod, ExpectedException(typeof(JobPersistenceException))] - public void RemoveCalendar_WhenActiveTriggerAssociatedWith_Unsuccessfully() { + public async Task RemoveCalendar_WhenActiveTriggerAssociatedWith_Unsuccessfully() + { //arrange + await JobStore.StoreCalendar("testCalendar", CreateCalendar(), false, false); + var job = CreateJob(); - JobStore.StoreJob(job,false); - var trigger = CreateTrigger("trigger", "triggerGroup", job.Key); - JobStore.StoreTrigger(trigger,false); + await JobStore.StoreJob(job, false); + var trigger = CreateTrigger("trigger", "triggerGroup", job.Key, calendarName: "testCalendar"); + await JobStore.StoreTrigger(trigger, false); //act - JobStore.RemoveCalendar(trigger.CalendarName); + await JobStore.RemoveCalendar(trigger.CalendarName); } } } diff --git a/QuartzRedisJobStore.UnitTest/JobFixture.cs b/QuartzRedisJobStore.UnitTest/JobFixture.cs index 50abe5a..feb6d7a 100644 --- a/QuartzRedisJobStore.UnitTest/JobFixture.cs +++ b/QuartzRedisJobStore.UnitTest/JobFixture.cs @@ -1,4 +1,6 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Quartz; using Quartz.Impl.Matchers; @@ -19,7 +21,7 @@ public class JobFixture : BaseFixture public void ClearAllJobStoreData() { System.Diagnostics.Debug.Write("here"); - JobStore?.ClearAllSchedulingData(); + JobStore?.ClearAllSchedulingData().Wait(); System.Diagnostics.Debug.Write(counter++); } @@ -33,44 +35,44 @@ public static void ClassCleanup() /// store a job /// [TestMethod] - public void StoreJobSuccessfully() + public async Task StoreJobSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); + await JobStore.StoreJob(job, false); //act - var jobData = Db.HashGetAll(Schema.JobHashKey(job.Key)); + var jobData = await Db.HashGetAllAsync(Schema.JobHashKey(job.Key)); //assert Assert.IsNotNull(jobData); - var description = (from j in jobData.ToList() + var description = (string)(from j in jobData.ToList() where j.Name == RedisJobStoreSchema.Description select j.Value).FirstOrDefault(); - Assert.AreEqual(description, "JobTesting"); + Assert.AreEqual("JobTesting", description); } /// /// store jobdatamap. /// [TestMethod] - public void StoreJobDataMapSuccessfully() + public async Task StoreJobDataMapSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); + await JobStore.StoreJob(job, false); //act - var jobData = Db.HashGetAll(Schema.JobDataMapHashKey(job.Key)); + var jobData = await Db.HashGetAllAsync(Schema.JobDataMapHashKey(job.Key)); //assert Assert.IsNotNull(jobData); - var data = (from j in jobData.ToList() + var data = (string)(from j in jobData.ToList() where j.Name == "testJob" select j.Value).FirstOrDefault(); - Assert.AreEqual(data, "testJob"); + Assert.AreEqual("testJob", data); } /// @@ -78,23 +80,27 @@ public void StoreJobDataMapSuccessfully() /// the original one will not be overriden. /// [TestMethod] - public void StoreJob_WithoutReplacingExisting_NoOverride() + public async Task StoreJob_WithoutReplacingExisting_NoOverride() { //arrange var job = CreateJob(); - JobStore.StoreJob(CreateJob(), false); - JobStore.StoreJob(CreateJob(description: "anotherDescription"), false); + await JobStore.StoreJob(CreateJob(), false); + try + { + await JobStore.StoreJob(CreateJob(description: "anotherDescription"), false); + } + catch { } //act - var jobData = Db.HashGetAll(Schema.JobHashKey(job.Key)); + var jobData = await Db.HashGetAllAsync(Schema.JobHashKey(job.Key)); //assert Assert.IsNotNull(jobData); - var description = (from j in jobData.ToList() + var description = (string)(from j in jobData.ToList() where j.Name == RedisJobStoreSchema.Description select j.Value).FirstOrDefault(); - Assert.AreEqual(description, "JobTesting"); + Assert.AreEqual("JobTesting", description); } /// @@ -102,37 +108,37 @@ public void StoreJob_WithoutReplacingExisting_NoOverride() /// the original one will be overriden. /// [TestMethod] - public void StoreJob_WithReplacingExisting_OverrideSuccessfully() + public async Task StoreJob_WithReplacingExisting_OverrideSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(CreateJob(), true); - JobStore.StoreJob(CreateJob(description: "anotherDescription"), true); + await JobStore.StoreJob(CreateJob(), true); + await JobStore.StoreJob(CreateJob(description: "anotherDescription"), true); //act - var jobData = Db.HashGetAll(Schema.JobHashKey(job.Key)); + var jobData = await Db.HashGetAllAsync(Schema.JobHashKey(job.Key)); //assert Assert.IsNotNull(jobData); - var description = (from j in jobData.ToList() + var description = (string)(from j in jobData.ToList() where j.Name == RedisJobStoreSchema.Description select j.Value).FirstOrDefault(); - Assert.AreEqual(description, "anotherDescription"); + Assert.AreEqual("anotherDescription", description); } /// /// retrieve a job /// [TestMethod] - public void RetreiveJobSuccessfully() + public async Task RetreiveJobSuccessfully() { //arrange var originalJob = CreateJob(); - JobStore.StoreJob(originalJob, true); + await JobStore.StoreJob(originalJob, true); //act - var retrievedJob = JobStore.RetrieveJob(originalJob.Key); + var retrievedJob = await JobStore.RetrieveJob(originalJob.Key); //assert Assert.IsNotNull(retrievedJob); @@ -144,37 +150,37 @@ public void RetreiveJobSuccessfully() /// remove a job /// [TestMethod] - public void RemoveJobSuccessfully() + public async Task RemoveJobSuccessfully() { //arrange var job = CreateJob("job1", "group1"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); //act - var result = JobStore.RemoveJob(job.Key); + var result = await JobStore.RemoveJob(job.Key); //assert Assert.IsTrue(result); - Assert.IsNull(JobStore.RetrieveJob(job.Key)); - Assert.IsNull(JobStore.RetrieveTrigger(trigger1.Key)); - Assert.IsNull(JobStore.RetrieveTrigger(trigger2.Key)); + Assert.IsNull(await JobStore.RetrieveJob(job.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger1.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger2.Key)); } /// /// remove jobs /// [TestMethod] - public void RemoveJobsSuccessfully() + public async Task RemoveJobsSuccessfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 1); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, true); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, true); //act - var result = JobStore.RemoveJobs((from job in jobsAndTriggers.Keys select job.Key).ToList()); + var result = await JobStore.RemoveJobs((from job in jobsAndTriggers.Keys select job.Key).ToList()); //assert Assert.IsTrue(result); @@ -184,15 +190,15 @@ public void RemoveJobsSuccessfully() /// Get total number of jobs in the store /// [TestMethod] - public void GetNumberOfJobsSuccessfully() + public async Task GetNumberOfJobsSuccessfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "group1"), true); - JobStore.StoreJob(CreateJob("job2", "group2"), true); - JobStore.StoreJob(CreateJob("job3", "group3"), true); + await JobStore.StoreJob(CreateJob("job1", "group1"), true); + await JobStore.StoreJob(CreateJob("job2", "group2"), true); + await JobStore.StoreJob(CreateJob("job3", "group3"), true); //act - var numberOfJobs = JobStore.GetNumberOfJobs(); + var numberOfJobs = await JobStore.GetNumberOfJobs(); //assert Assert.IsTrue(numberOfJobs == 3); @@ -202,15 +208,15 @@ public void GetNumberOfJobsSuccessfully() /// get the jobs in which its group is group1 /// [TestMethod] - public void GetJobKeys_UseEqualOperator_Successfully() + public async Task GetJobKeys_UseEqualOperator_Successfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "group1"), true); - JobStore.StoreJob(CreateJob("job2", "group1"), true); - JobStore.StoreJob(CreateJob("job3", "group3"), true); + await JobStore.StoreJob(CreateJob("job1", "group1"), true); + await JobStore.StoreJob(CreateJob("job2", "group1"), true); + await JobStore.StoreJob(CreateJob("job3", "group3"), true); //act - var jobKeys = JobStore.GetJobKeys(GroupMatcher.GroupEquals("group1")); + var jobKeys = await JobStore.GetJobKeys(GroupMatcher.GroupEquals("group1")); //assert Assert.IsTrue(jobKeys.Count == 2); @@ -220,15 +226,15 @@ public void GetJobKeys_UseEqualOperator_Successfully() /// get the jobs in which its group contains group0 /// [TestMethod] - public void GetJobKeys_UseContainOperator_Successfully() + public async Task GetJobKeys_UseContainOperator_Successfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "group01"), true); - JobStore.StoreJob(CreateJob("job2", "group01"), true); - JobStore.StoreJob(CreateJob("job3", "group03"), true); + await JobStore.StoreJob(CreateJob("job1", "group01"), true); + await JobStore.StoreJob(CreateJob("job2", "group01"), true); + await JobStore.StoreJob(CreateJob("job3", "group03"), true); //act - var jobKeys = JobStore.GetJobKeys(GroupMatcher.GroupContains("group0")); + var jobKeys = await JobStore.GetJobKeys(GroupMatcher.GroupContains("group0")); //assert Assert.IsTrue(jobKeys.Count == 3); @@ -238,15 +244,15 @@ public void GetJobKeys_UseContainOperator_Successfully() /// get the jobs in which its group ends with s /// [TestMethod] - public void GetJobKeys_UseEndsWithOperator_Successfully() + public async Task GetJobKeys_UseEndsWithOperator_Successfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "group01s"), true); - JobStore.StoreJob(CreateJob("job2", "group01s"), true); - JobStore.StoreJob(CreateJob("job3", "group03s"), true); + await JobStore.StoreJob(CreateJob("job1", "group01s"), true); + await JobStore.StoreJob(CreateJob("job2", "group01s"), true); + await JobStore.StoreJob(CreateJob("job3", "group03s"), true); //act - var jobKeys = JobStore.GetJobKeys(GroupMatcher.GroupEndsWith("s")); + var jobKeys = await JobStore.GetJobKeys(GroupMatcher.GroupEndsWith("s")); //assert Assert.IsTrue(jobKeys.Count == 3); @@ -256,15 +262,15 @@ public void GetJobKeys_UseEndsWithOperator_Successfully() /// get the jobs in which its group starts with groups /// [TestMethod] - public void GetJobKeys_UseStartsWithOperator_Successfully() + public async Task GetJobKeys_UseStartsWithOperator_Successfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "groups1"), true); - JobStore.StoreJob(CreateJob("job2", "groups2"), true); - JobStore.StoreJob(CreateJob("job3", "groups3"), true); + await JobStore.StoreJob(CreateJob("job1", "groups1"), true); + await JobStore.StoreJob(CreateJob("job2", "groups2"), true); + await JobStore.StoreJob(CreateJob("job3", "groups3"), true); //act - var jobKeys = JobStore.GetJobKeys(GroupMatcher.GroupStartsWith("groups")); + var jobKeys = await JobStore.GetJobKeys(GroupMatcher.GroupStartsWith("groups")); //assert Assert.IsTrue(jobKeys.Count == 3); @@ -274,15 +280,15 @@ public void GetJobKeys_UseStartsWithOperator_Successfully() /// get all the group name in the store /// [TestMethod] - public void GetJobGroupNamesSuccessfully() + public async Task GetJobGroupNamesSuccessfully() { //arrange - JobStore.StoreJob(CreateJob("job1", "groups1"), true); - JobStore.StoreJob(CreateJob("job2", "groups2"), true); + await JobStore.StoreJob(CreateJob("job1", "groups1"), true); + await JobStore.StoreJob(CreateJob("job2", "groups2"), true); //act - var groups = JobStore.GetJobGroupNames(); + var groups = await JobStore.GetJobGroupNames(); //assert Assert.IsTrue(groups.Count == 2); @@ -292,36 +298,36 @@ public void GetJobGroupNamesSuccessfully() /// pause a job /// [TestMethod] - public void PauseJobSuccessfully() + public async Task PauseJobSuccessfully() { //arrange var job = CreateJob("pausedJob", "pausedGroup"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); //act - JobStore.PauseJob(job.Key); + await JobStore.PauseJob(job.Key); //assert - Assert.AreEqual(JobStore.GetTriggerState(trigger1.Key), TriggerState.Paused); - Assert.AreEqual(JobStore.GetTriggerState(trigger2.Key), TriggerState.Paused); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger2.Key)); } /// /// Pause all the job which their group equals jobGroup_1 /// [TestMethod] - public void PauseJobs_UseEqualOperator_Successfully() + public async Task PauseJobs_UseEqualOperator_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); var pausedGroup = jobsAndTriggers.First().Key.Key.Group; //act - JobStore.PauseJobs(GroupMatcher.GroupEquals(pausedGroup)); + await JobStore.PauseJobs(GroupMatcher.GroupEquals(pausedGroup)); //assert foreach (var job in jobsAndTriggers.Keys) @@ -331,16 +337,12 @@ public void PauseJobs_UseEqualOperator_Successfully() if (job.Key.Group == pausedGroup) { foreach (var trigger in triggers) - { - Assert.AreEqual(JobStore.GetTriggerState(trigger.Key), TriggerState.Paused); - } + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger.Key)); } else { foreach (var trigger in triggers) - { - Assert.AreEqual(JobStore.GetTriggerState(trigger.Key), TriggerState.Normal); - } + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } } } @@ -349,88 +351,88 @@ public void PauseJobs_UseEqualOperator_Successfully() /// Pause all the job which their group starts with start /// [TestMethod] - public void PauseJobs_UseStartsWithOperator_Successfully() + public async Task PauseJobs_UseStartsWithOperator_Successfully() { //arrange var job = CreateJob("job1", "startGroup"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); //act - var pausedJobs = JobStore.PauseJobs(GroupMatcher.GroupStartsWith("start")); + var pausedJobs = await JobStore.PauseJobs(GroupMatcher.GroupStartsWith("start")); //assert Assert.IsTrue(pausedJobs.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger2.Key)); } /// /// Pause all the job which their group ends with Ends /// [TestMethod] - public void PauseJobs_UseEndssWithOperator_Successfully() + public async Task PauseJobs_UseEndssWithOperator_Successfully() { //arrange var job = CreateJob("job1", "GroupEnds"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); //act - var pausedJobs = JobStore.PauseJobs(GroupMatcher.GroupEndsWith("Ends")); + var pausedJobs = await JobStore.PauseJobs(GroupMatcher.GroupEndsWith("Ends")); //assert Assert.IsTrue(pausedJobs.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger2.Key)); } /// /// Pause all the job which their group contains foobar /// [TestMethod] - public void PauseJobs_UseContainWithsOperator_Successfully() + public async Task PauseJobs_UseContainWithsOperator_Successfully() { //arrange var job = CreateJob("job1", "GroupContainsfoobar"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); //act - var pausedJobs = JobStore.PauseJobs(GroupMatcher.GroupContains("foobar")); + var pausedJobs = await JobStore.PauseJobs(GroupMatcher.GroupContains("foobar")); //assert Assert.IsTrue(pausedJobs.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger2.Key)); } /// /// resume a job /// [TestMethod] - public void ResumeJobSuccessfully() + public async Task ResumeJobSuccessfully() { //arrange var job = CreateJob("job1", "jobGroup1"); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup2", job.Key); - var triggerSet = new global::Quartz.Collection.HashSet { trigger1, trigger2 }; - this.StoreJobAndTriggers(job, triggerSet); - JobStore.PauseJob(job.Key); + var triggerSet = new HashSet { trigger1, trigger2 }; + await this.StoreJobAndTriggers(job, triggerSet); + await JobStore.PauseJob(job.Key); //act - JobStore.ResumeJob(job.Key); + await JobStore.ResumeJob(job.Key); //assert - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger2.Key)); } @@ -438,18 +440,18 @@ public void ResumeJobSuccessfully() /// resume all the job which their group equals jobGroup_1 /// [TestMethod] - public void ResumeJobs_UseEqualOperator_Successfully() + public async Task ResumeJobs_UseEqualOperator_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 2, 2, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); var pausedGroup = jobsAndTriggers.Keys.First().Key.Group; - JobStore.PauseJobs(GroupMatcher.GroupEquals(pausedGroup)); - global::Quartz.Collection.ISet triggers = new global::Quartz.Collection.HashSet(); + await JobStore.PauseJobs(GroupMatcher.GroupEquals(pausedGroup)); + IReadOnlyCollection triggers = new HashSet(); jobsAndTriggers.TryGetValue(jobsAndTriggers.Keys.First(), out triggers); //act - var resumedJobGroups = JobStore.ResumeJobs(GroupMatcher.GroupEquals(pausedGroup)); + var resumedJobGroups = await JobStore.ResumeJobs(GroupMatcher.GroupEquals(pausedGroup)); //assert Assert.IsTrue(resumedJobGroups.Count == 1); @@ -458,7 +460,7 @@ public void ResumeJobs_UseEqualOperator_Successfully() //all its triggers are back to the Normal state foreach (var trigger in triggers) { - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } } @@ -466,18 +468,18 @@ public void ResumeJobs_UseEqualOperator_Successfully() /// resume all the job which their group ends with _1 /// [TestMethod] - public void ResumeJobs_UseEndsWithOperator_Successfully() + public async Task ResumeJobs_UseEndsWithOperator_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 2, 2, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); - JobStore.PauseJobs(GroupMatcher.GroupEndsWith("_1")); - global::Quartz.Collection.ISet triggers = new global::Quartz.Collection.HashSet(); + await JobStore.PauseJobs(GroupMatcher.GroupEndsWith("_1")); + IReadOnlyCollection triggers = new HashSet(); jobsAndTriggers.TryGetValue(jobsAndTriggers.Keys.First(), out triggers); //act - var resumedJobGroups = JobStore.ResumeJobs(GroupMatcher.GroupEndsWith("_1")); + var resumedJobGroups = await JobStore.ResumeJobs(GroupMatcher.GroupEndsWith("_1")); //assert Assert.IsTrue(resumedJobGroups.Count == 1); @@ -485,7 +487,7 @@ public void ResumeJobs_UseEndsWithOperator_Successfully() //all its triggers are back to the Normal state foreach (var trigger in triggers) { - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } } @@ -493,15 +495,15 @@ public void ResumeJobs_UseEndsWithOperator_Successfully() /// resume all the job which their group starts with jobGroup_ /// [TestMethod] - public void ResumeJobs_UseStartsWithOperator_Successfully() + public async Task ResumeJobs_UseStartsWithOperator_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 1); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); - JobStore.PauseJobs(GroupMatcher.GroupStartsWith("jobGroup_")); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.PauseJobs(GroupMatcher.GroupStartsWith("jobGroup_")); //act - var resumedJobGroups = JobStore.ResumeJobs(GroupMatcher.GroupStartsWith("jobGroup_")); + var resumedJobGroups = await JobStore.ResumeJobs(GroupMatcher.GroupStartsWith("jobGroup_")); //assert Assert.IsTrue(resumedJobGroups.Count == 2); @@ -511,15 +513,15 @@ public void ResumeJobs_UseStartsWithOperator_Successfully() /// resume all the job which their group contains _ /// [TestMethod] - public void ResumeJobs_UseContainsWithOperator_Successfully() + public async Task ResumeJobs_UseContainsWithOperator_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 2, 2, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); - JobStore.PauseJobs(GroupMatcher.GroupContains("_")); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.PauseJobs(GroupMatcher.GroupContains("_")); //act - var resumedJobGroups = JobStore.ResumeJobs(GroupMatcher.GroupContains("_")); + var resumedJobGroups = await JobStore.ResumeJobs(GroupMatcher.GroupContains("_")); //assert Assert.IsTrue(resumedJobGroups.Count == 2); diff --git a/QuartzRedisJobStore.UnitTest/QuartzRedisJobStore.UnitTest.csproj b/QuartzRedisJobStore.UnitTest/QuartzRedisJobStore.UnitTest.csproj index 7c27e77..c22a964 100644 --- a/QuartzRedisJobStore.UnitTest/QuartzRedisJobStore.UnitTest.csproj +++ b/QuartzRedisJobStore.UnitTest/QuartzRedisJobStore.UnitTest.csproj @@ -8,7 +8,7 @@ Properties QuartzRedisJobStore.UnitTest QuartzRedisJobStore.UnitTest - v4.5.2 + v4.6.1 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -16,6 +16,7 @@ $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages False UnitTest + true @@ -43,24 +44,79 @@ ..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll True + + ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + + + ..\packages\Microsoft.Extensions.DependencyInjection.5.0.2\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\packages\Microsoft.Extensions.Logging.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Logging.Abstractions.dll + ..\packages\Moq.4.2.1507.0118\lib\net40\Moq.dll True - - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - True + + ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll - - ..\packages\Quartz.2.3.3\lib\net40\Quartz.dll - True + + ..\packages\Pipelines.Sockets.Unofficial.2.2.0\lib\net461\Pipelines.Sockets.Unofficial.dll - - ..\packages\StackExchange.Redis.1.0.481\lib\net45\StackExchange.Redis.dll - True + + ..\packages\Quartz.3.2.3\lib\net461\Quartz.dll + + + ..\packages\Quartz.Serialization.Json.3.2.3\lib\net461\Quartz.Serialization.Json.dll + + + ..\packages\StackExchange.Redis.1.2.6\lib\net46\StackExchange.Redis.dll + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\packages\System.Diagnostics.DiagnosticSource.5.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Diagnostics.PerformanceCounter.5.0.0\lib\net461\System.Diagnostics.PerformanceCounter.dll + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + True + + + ..\packages\System.IO.Pipelines.5.0.0\lib\net461\System.IO.Pipelines.dll + + + ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + + ..\packages\System.Threading.Channels.5.0.0\lib\net461\System.Threading.Channels.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + diff --git a/QuartzRedisJobStore.UnitTest/RedisJobStoreFixture.cs b/QuartzRedisJobStore.UnitTest/RedisJobStoreFixture.cs index eb9bb59..452cea1 100644 --- a/QuartzRedisJobStore.UnitTest/RedisJobStoreFixture.cs +++ b/QuartzRedisJobStore.UnitTest/RedisJobStoreFixture.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Quartz; using Quartz.Impl; @@ -18,7 +19,7 @@ public class RedisJobStoreFixture : BaseFixture public void ClearAllJobStoreData() { System.Diagnostics.Debug.Write("here"); - JobStore?.ClearAllSchedulingData(); + JobStore?.ClearAllSchedulingData().Wait(); System.Diagnostics.Debug.Write(counter++); } @@ -33,23 +34,23 @@ public static void ClassCleanup() /// check job and trigger are actually saved. /// [TestMethod] - public void StartScheduler_WithJobsAndTriggers_SavedSuccessfully() + public async Task StartScheduler_WithJobsAndTriggers_SavedSuccessfully() { //arrange ISchedulerFactory sf = new StdSchedulerFactory(); - IScheduler sched = sf.GetScheduler(); + IScheduler sched = await sf.GetScheduler(); var job = CreateJob(); var trigger = CreateTrigger("testTrigger1", "triggerGroup", job.Key, "0/5 * * * * ?"); var calendar = CreateCalendar(); //act - sched.AddCalendar("testCalendar", calendar, false, false); - sched.ScheduleJob(job, trigger); - sched.Start(); - sched.Shutdown(); + await sched.AddCalendar("testCalendar", calendar, false, false); + await sched.ScheduleJob(job, trigger); + await sched.Start(); + await sched.Shutdown(); //assert - Assert.IsNotNull(JobStore.RetrieveJob(job.Key)); - Assert.IsNotNull(JobStore.RetrieveTrigger(trigger.Key)); + Assert.IsNotNull(await JobStore.RetrieveJob(job.Key)); + Assert.IsNotNull(await JobStore.RetrieveTrigger(trigger.Key)); } /// @@ -57,25 +58,25 @@ public void StartScheduler_WithJobsAndTriggers_SavedSuccessfully() /// check job and its trigger are deleted from the store. /// [TestMethod] - public void StartScheduler_WithJobsAndTriggers_DeletedSuccessfully() + public async Task StartScheduler_WithJobsAndTriggers_DeletedSuccessfully() { //arrange ISchedulerFactory sf = new StdSchedulerFactory(); - IScheduler sched = sf.GetScheduler(); + IScheduler sched = await sf.GetScheduler(); var job = CreateJob(); var trigger = CreateTrigger("testTrigger1", "triggerGroup", job.Key, "0/5 * * * * ?"); var calendar = CreateCalendar(); - sched.AddCalendar("testCalendar", calendar, false, false); - sched.ScheduleJob(job, trigger); - sched.Start(); + await sched.AddCalendar("testCalendar", calendar, false, false); + await sched.ScheduleJob(job, trigger); + await sched.Start(); //act - sched.DeleteJob(job.Key); - sched.Shutdown(); + await sched.DeleteJob(job.Key); + await sched.Shutdown(); //assert - Assert.IsNull(JobStore.RetrieveJob(job.Key)); - Assert.IsNull(JobStore.RetrieveTrigger(trigger.Key)); + Assert.IsNull(await JobStore.RetrieveJob(job.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger.Key)); } } diff --git a/QuartzRedisJobStore.UnitTest/TestJobs.cs b/QuartzRedisJobStore.UnitTest/TestJobs.cs index dfc55bb..9f44ead 100644 --- a/QuartzRedisJobStore.UnitTest/TestJobs.cs +++ b/QuartzRedisJobStore.UnitTest/TestJobs.cs @@ -1,4 +1,5 @@ using Quartz; +using System.Threading.Tasks; namespace QuartzRedisJobStore.UnitTest { @@ -21,8 +22,8 @@ public class TestJob : IJob /// execution. /// /// The execution context. - public void Execute(IJobExecutionContext context) { - + public Task Execute(IJobExecutionContext context) { + return Task.CompletedTask; } #endregion } diff --git a/QuartzRedisJobStore.UnitTest/TriggerFixture.cs b/QuartzRedisJobStore.UnitTest/TriggerFixture.cs index 6be429c..b6cbfea 100644 --- a/QuartzRedisJobStore.UnitTest/TriggerFixture.cs +++ b/QuartzRedisJobStore.UnitTest/TriggerFixture.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Quartz; using Quartz.Impl.Calendar; @@ -22,7 +23,7 @@ public class TriggerFixture : BaseFixture public void ClearAllJobStoreData() { System.Diagnostics.Debug.Write("here"); - JobStore?.ClearAllSchedulingData(); + JobStore?.ClearAllSchedulingData().Wait(); System.Diagnostics.Debug.Write(counter++); } @@ -36,29 +37,29 @@ public static void ClassCleanup() /// store a trigger /// [TestMethod] - public void StoreTriggerSuccessfully() + public async Task StoreTriggerSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); + await JobStore.StoreJob(job, true); var trigger = CreateTrigger("tt", "tt", job.Key); var triggerHashKey = Schema.TriggerHashkey(trigger.Key); //act - JobStore.StoreTrigger(trigger, false); + await JobStore.StoreTrigger(trigger, false); //assert - var triggerProperties = Db.HashGetAll(triggerHashKey); + var triggerProperties = await Db.HashGetAllAsync(triggerHashKey); Assert.IsNotNull(triggerProperties); - var className = + var className = (string) (from hashEntry in triggerProperties where hashEntry.Name == RedisJobStoreSchema.TriggerType select hashEntry.Value).FirstOrDefault(); - Assert.AreEqual(className, RedisJobStoreSchema.TriggerTypeCron); - Assert.IsTrue(Db.SetContains(Schema.TriggersSetKey(), triggerHashKey)); - Assert.IsTrue(Db.SetContains(Schema.TriggerGroupsSetKey(), Schema.TriggerGroupSetKey(trigger.Key.Group))); - Assert.IsTrue(Db.SetContains(Schema.TriggerGroupSetKey(trigger.Key.Group), triggerHashKey)); - Assert.IsTrue(Db.SetContains(Schema.JobTriggersSetKey(trigger.JobKey), triggerHashKey)); + Assert.AreEqual(RedisJobStoreSchema.TriggerTypeCron, className); + Assert.IsTrue(await Db.SetContainsAsync(Schema.TriggersSetKey(), triggerHashKey)); + Assert.IsTrue(await Db.SetContainsAsync(Schema.TriggerGroupsSetKey(), Schema.TriggerGroupSetKey(trigger.Key.Group))); + Assert.IsTrue(await Db.SetContainsAsync(Schema.TriggerGroupSetKey(trigger.Key.Group), triggerHashKey)); + Assert.IsTrue(await Db.SetContainsAsync(Schema.JobTriggersSetKey(trigger.JobKey), triggerHashKey)); } /// @@ -66,20 +67,24 @@ public void StoreTriggerSuccessfully() /// the original one will not be overriden. /// [TestMethod] - public void StoreTrigger_WithoutReplacingExisting_NoOverride() + public async Task StoreTrigger_WithoutReplacingExisting_NoOverride() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); + await JobStore.StoreJob(job, true); var trigger = CreateTrigger("tt", "tt", job.Key); var trigger1 = CreateTrigger("tt", "tt", job.Key, "0 0 12 * * ?"); //act - JobStore.StoreTrigger(trigger, false); - JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger, false); + try + { + await JobStore.StoreTrigger(trigger1, false); + } + catch { } //assert - var retrievedTrigger = (CronTriggerImpl)JobStore.RetrieveTrigger(trigger.Key); + var retrievedTrigger = (CronTriggerImpl)(await JobStore.RetrieveTrigger(trigger.Key)); Assert.AreEqual(retrievedTrigger.CronExpressionString, "0 0 0 * * ?"); } @@ -88,20 +93,20 @@ public void StoreTrigger_WithoutReplacingExisting_NoOverride() /// the original one will be overriden. /// [TestMethod] - public void StoreTrigger_WithReplacingExisting_OverrideSuccessfully() + public async Task StoreTrigger_WithReplacingExisting_OverrideSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); + await JobStore.StoreJob(job, true); var trigger = CreateTrigger("tt", "tt", job.Key); var trigger1 = CreateTrigger("tt", "tt", job.Key, "0 0 12 * * ?"); //act - JobStore.StoreTrigger(trigger, true); - JobStore.StoreTrigger(trigger1, true); + await JobStore.StoreTrigger(trigger, true); + await JobStore.StoreTrigger(trigger1, true); //assert - var retrievedTrigger = (CronTriggerImpl)JobStore.RetrieveTrigger(trigger.Key); + var retrievedTrigger = (CronTriggerImpl)(await JobStore.RetrieveTrigger(trigger.Key)); Assert.AreEqual(retrievedTrigger.CronExpressionString, "0 0 12 * * ?"); } @@ -109,18 +114,18 @@ public void StoreTrigger_WithReplacingExisting_OverrideSuccessfully() /// retrieve a trigger /// [TestMethod] - public void RetrieveTriggerSuccessfully() + public async Task RetrieveTriggerSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); + await JobStore.StoreJob(job, true); var trigger = CreateTrigger("tt", "tt", job.Key); //act - JobStore.StoreTrigger(trigger, true); + await JobStore.StoreTrigger(trigger, true); //assert - var retrievedTrigger = (CronTriggerImpl)JobStore.RetrieveTrigger(trigger.Key); + var retrievedTrigger = (CronTriggerImpl)(await JobStore.RetrieveTrigger(trigger.Key)); Assert.AreEqual(retrievedTrigger.CronExpressionString, "0 0 0 * * ?"); } @@ -129,7 +134,7 @@ public void RetrieveTriggerSuccessfully() /// check the job iteself still there and only that deleted trigger is removed. /// [TestMethod] - public void RemoveTrigger_RemoveOneOutOfTwo_Successfully() + public async Task RemoveTrigger_RemoveOneOutOfTwo_Successfully() { //arrange var job = CreateJob(); @@ -137,16 +142,16 @@ public void RemoveTrigger_RemoveOneOutOfTwo_Successfully() var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); //act - JobStore.RemoveTrigger(trigger1.Key); + await JobStore.RemoveTrigger(trigger1.Key); //assert - Assert.IsNull(JobStore.RetrieveTrigger(trigger1.Key)); - Assert.IsNotNull(JobStore.RetrieveJob(trigger1.JobKey)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger1.Key)); + Assert.IsNotNull(await JobStore.RetrieveJob(trigger1.JobKey)); } /// @@ -154,7 +159,7 @@ public void RemoveTrigger_RemoveOneOutOfTwo_Successfully() /// check the job and triggers are removed since the job itself is not durable. /// [TestMethod] - public void RemoveTrigger_RemoveTwoOutOfTwo_Successfully() + public async Task RemoveTrigger_RemoveTwoOutOfTwo_Successfully() { //arrange var job = CreateJob(); @@ -162,18 +167,18 @@ public void RemoveTrigger_RemoveTwoOutOfTwo_Successfully() var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); //act - JobStore.RemoveTrigger(trigger1.Key); - JobStore.RemoveTrigger(trigger2.Key); + await JobStore.RemoveTrigger(trigger1.Key); + await JobStore.RemoveTrigger(trigger2.Key); //assert - Assert.IsNull(JobStore.RetrieveTrigger(trigger1.Key)); - Assert.IsNull(JobStore.RetrieveTrigger(trigger2.Key)); - Assert.IsNull(JobStore.RetrieveJob(trigger1.JobKey)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger1.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger2.Key)); + Assert.IsNull(await JobStore.RetrieveJob(trigger1.JobKey)); } /// @@ -181,7 +186,7 @@ public void RemoveTrigger_RemoveTwoOutOfTwo_Successfully() /// check the job still there only triggers are removed since the job itself is durable. /// [TestMethod] - public void RemoveTriggerForDurableJob_RemoveTwoOutOfTwo_Successfully() + public async Task RemoveTriggerForDurableJob_RemoveTwoOutOfTwo_Successfully() { //arrange var job = JobBuilder.Create() @@ -194,25 +199,25 @@ public void RemoveTriggerForDurableJob_RemoveTwoOutOfTwo_Successfully() var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); //act - JobStore.RemoveTrigger(trigger1.Key); - JobStore.RemoveTrigger(trigger2.Key); + await JobStore.RemoveTrigger(trigger1.Key); + await JobStore.RemoveTrigger(trigger2.Key); //assert - Assert.IsNull(JobStore.RetrieveTrigger(trigger1.Key)); - Assert.IsNull(JobStore.RetrieveTrigger(trigger2.Key)); - Assert.IsNotNull(JobStore.RetrieveJob(trigger1.JobKey)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger1.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger2.Key)); + Assert.IsNotNull(await JobStore.RetrieveJob(trigger1.JobKey)); } /// /// retrieve the triggers for the job /// [TestMethod] - public void GetTriggersForJob_Successfully() + public async Task GetTriggersForJob_Successfully() { //arrange var job = CreateJob(); @@ -220,12 +225,12 @@ public void GetTriggersForJob_Successfully() var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); //act - var triggers = JobStore.GetTriggersForJob(job.Key); + var triggers = await JobStore.GetTriggersForJob(job.Key); //assert Assert.IsTrue(triggers.Count == 2); @@ -235,14 +240,14 @@ public void GetTriggersForJob_Successfully() /// get the total number of triggers in the store. /// [TestMethod] - public void GetNumberOfTriggers_Successfully() + public async Task GetNumberOfTriggers_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); //act - var result = JobStore.GetNumberOfTriggers(); + var result = await JobStore.GetNumberOfTriggers(); //assert Assert.AreEqual(result, 4); @@ -251,18 +256,18 @@ public void GetNumberOfTriggers_Successfully() /// /// get all the trigger which their group equals triggerGroup /// - public void GetTriggerKeys_UseEqualOperator_Successfully() + public async Task GetTriggerKeys_UseEqualOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerGroup1", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerGroup1", job.Key), false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerGroup1", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerGroup1", job.Key), false); //act - var triggerKeys = JobStore.GetTriggerKeys(GroupMatcher.GroupEquals("triggerGroup")); + var triggerKeys = await JobStore.GetTriggerKeys(GroupMatcher.GroupEquals("triggerGroup")); //assert Assert.IsTrue(triggerKeys.Count == 2); @@ -272,18 +277,18 @@ public void GetTriggerKeys_UseEqualOperator_Successfully() /// get all the trigger which their group starts with triggerGroup /// [TestMethod] - public void GetTriggerKeys_UseStartsWithOperator_Successfully() + public async Task GetTriggerKeys_UseStartsWithOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(CreateTrigger("trigger1", "tGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger2", "tGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger3", "tGroup1", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger4", "tGroup1", job.Key), false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "tGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "tGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "tGroup1", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "tGroup1", job.Key), false); //act - var triggerKeys = JobStore.GetTriggerKeys(GroupMatcher.GroupStartsWith("tGroup")); + var triggerKeys = await JobStore.GetTriggerKeys(GroupMatcher.GroupStartsWith("tGroup")); //assert Assert.IsTrue(triggerKeys.Count == 4); @@ -293,18 +298,18 @@ public void GetTriggerKeys_UseStartsWithOperator_Successfully() /// get all the trigger which their group ends with 1 /// [TestMethod] - public void GetTriggerKeys_UseEndsWithOperator_Successfully() + public async Task GetTriggerKeys_UseEndsWithOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerGroup1", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerGroup1", job.Key), false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerGroup1", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerGroup1", job.Key), false); //act - var triggerKeys = JobStore.GetTriggerKeys(GroupMatcher.GroupEndsWith("1")); + var triggerKeys = await JobStore.GetTriggerKeys(GroupMatcher.GroupEndsWith("1")); //assert Assert.IsTrue(triggerKeys.Count == 2); @@ -314,18 +319,18 @@ public void GetTriggerKeys_UseEndsWithOperator_Successfully() /// get all the trigger which their group contains foobar /// [TestMethod] - public void GetTriggerKeys_UseContainsOperator_Successfully() + public async Task GetTriggerKeys_UseContainsOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), false); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), false); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), false); //act - var triggerKeys = JobStore.GetTriggerKeys(GroupMatcher.GroupContains("foobar")); + var triggerKeys = await JobStore.GetTriggerKeys(GroupMatcher.GroupContains("foobar")); //assert Assert.IsTrue(triggerKeys.Count == 2); @@ -335,14 +340,14 @@ public void GetTriggerKeys_UseContainsOperator_Successfully() /// get all the trigger group in the store /// [TestMethod] - public void GetTriggerGroupNames_Successfully() + public async Task GetTriggerGroupNames_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); //act - var result = JobStore.GetTriggerGroupNames(); + var result = await JobStore.GetTriggerGroupNames(); //assert Assert.AreEqual(result.Count, 2); @@ -352,140 +357,141 @@ public void GetTriggerGroupNames_Successfully() /// check the newly saved trigger is in the normal state. /// [TestMethod] - public void GetTriggerState_NewlyStoredTrigger_NormalStateIsReturnedSuccessfully() + public async Task GetTriggerState_NewlyStoredTrigger_NormalStateIsReturnedSuccessfully() { //arrange var job = CreateJob(); + await JobStore.StoreJob(job, false); var trigger = CreateTrigger("trigger1", "triggerGroup1", job.Key); //act - JobStore.StoreTrigger(trigger, false); + await JobStore.StoreTrigger(trigger, false); //assert - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } /// /// pause all the trigger which their group equals triggerfoobarGroup1 /// [TestMethod] - public void PauseTriggers_UseEqualOperator_Successfully() + public async Task PauseTriggers_UseEqualOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); //act - var pausedGroups = JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerfoobarGroup1")); + var pausedGroups = await JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerfoobarGroup1")); //assert Assert.IsTrue(pausedGroups.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); } /// /// pause all the trigger which their group starts with triggerfooba /// [TestMethod] - public void PauseTriggers_UseStartsWithOperator_Successfully() + public async Task PauseTriggers_UseStartsWithOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); //act - var pausedGroups = JobStore.PauseTriggers(GroupMatcher.GroupStartsWith("triggerfooba")); + var pausedGroups = await JobStore.PauseTriggers(GroupMatcher.GroupStartsWith("triggerfooba")); //assert Assert.IsTrue(pausedGroups.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); } /// /// pause all the trigger which their group ends with 1 /// [TestMethod] - public void PauseTriggers_UseEndsWithOperator_Successfully() + public async Task PauseTriggers_UseEndsWithOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); //act - var pausedGroups = JobStore.PauseTriggers(GroupMatcher.GroupEndsWith("1")); + var pausedGroups = await JobStore.PauseTriggers(GroupMatcher.GroupEndsWith("1")); //assert Assert.IsTrue(pausedGroups.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); } /// /// pause all the trigger which their group contains foobar /// [TestMethod] - public void PauseTriggers_UseContainsOperator_Successfully() + public async Task PauseTriggers_UseContainsOperator_Successfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup1", job.Key), true); //act - var pausedGroups = JobStore.PauseTriggers(GroupMatcher.GroupContains("foobar")); + var pausedGroups = await JobStore.PauseTriggers(GroupMatcher.GroupContains("foobar")); //assert Assert.IsTrue(pausedGroups.Count == 1); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger3", "triggerfoobarGroup1"))); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(new TriggerKey("trigger4", "triggerfoobarGroup1"))); } /// /// resume a trigger /// [TestMethod] - public void ResumeTriggerSuccessfully() + public async Task ResumeTriggerSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, false); + await JobStore.StoreJob(job, false); var trigger = CreateTrigger("trigger1", "triggerGroup", job.Key); - JobStore.StoreTrigger(trigger, false); - JobStore.PauseTrigger(trigger.Key); + await JobStore.StoreTrigger(trigger, false); + await JobStore.PauseTrigger(trigger.Key); //act - JobStore.ResumeTrigger(trigger.Key); + await JobStore.ResumeTrigger(trigger.Key); //assert - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } /// /// resume all the trigger which their group equals triggerGroup /// [TestMethod] - public void ResumeTrigger_UseEqualOperator_Successfully() + public async Task ResumeTrigger_UseEqualOperator_Successfully() { //arrange var job = CreateJob(); @@ -495,28 +501,28 @@ public void ResumeTrigger_UseEqualOperator_Successfully() var trigger3 = CreateTrigger("trigger3", "triggerGroup1", job.Key); var trigger4 = CreateTrigger("trigger4", "triggerGroup1", job.Key); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(trigger1, true); - JobStore.StoreTrigger(trigger2, true); - JobStore.StoreTrigger(trigger3, true); - JobStore.StoreTrigger(trigger4, true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(trigger1, true); + await JobStore.StoreTrigger(trigger2, true); + await JobStore.StoreTrigger(trigger3, true); + await JobStore.StoreTrigger(trigger4, true); - JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerGroup")); + await JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerGroup")); //act - var resumedGroups = JobStore.ResumeTriggers(GroupMatcher.GroupEquals("triggerGroup")); + var resumedGroups = await JobStore.ResumeTriggers(GroupMatcher.GroupEquals("triggerGroup")); //assert Assert.IsTrue(resumedGroups.Count == 1); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger2.Key)); } /// /// resume all the trigger which their group starts with trigger1 /// [TestMethod] - public void ResumeTrigger_UseStartsWithOperator_Successfully() + public async Task ResumeTrigger_UseStartsWithOperator_Successfully() { //arrange var job = CreateJob(); @@ -526,28 +532,28 @@ public void ResumeTrigger_UseStartsWithOperator_Successfully() var trigger3 = CreateTrigger("trigger3", "triggerGroup1", job.Key); var trigger4 = CreateTrigger("trigger4", "triggerGroup1", job.Key); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(trigger1, true); - JobStore.StoreTrigger(trigger2, true); - JobStore.StoreTrigger(trigger3, true); - JobStore.StoreTrigger(trigger4, true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(trigger1, true); + await JobStore.StoreTrigger(trigger2, true); + await JobStore.StoreTrigger(trigger3, true); + await JobStore.StoreTrigger(trigger4, true); - JobStore.PauseTriggers(GroupMatcher.GroupStartsWith("trigger1")); + await JobStore.PauseTriggers(GroupMatcher.GroupStartsWith("trigger1")); //act - var resumedGroups = JobStore.ResumeTriggers(GroupMatcher.GroupStartsWith("trigger1")); + var resumedGroups = await JobStore.ResumeTriggers(GroupMatcher.GroupStartsWith("trigger1")); //assert Assert.IsTrue(resumedGroups.Count == 1); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger1.Key)); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger2.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger1.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger2.Key)); } /// /// resume all the trigger which their group ends with Group1 /// [TestMethod] - public void ResumeTrigger_UseEndsWithOperator_Successfully() + public async Task ResumeTrigger_UseEndsWithOperator_Successfully() { //arrange var job = CreateJob(); @@ -557,28 +563,28 @@ public void ResumeTrigger_UseEndsWithOperator_Successfully() var trigger3 = CreateTrigger("trigger3", "triggerGroup1", job.Key); var trigger4 = CreateTrigger("trigger4", "triggerGroup1", job.Key); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(trigger1, true); - JobStore.StoreTrigger(trigger2, true); - JobStore.StoreTrigger(trigger3, true); - JobStore.StoreTrigger(trigger4, true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(trigger1, true); + await JobStore.StoreTrigger(trigger2, true); + await JobStore.StoreTrigger(trigger3, true); + await JobStore.StoreTrigger(trigger4, true); - JobStore.PauseTriggers(GroupMatcher.GroupEndsWith("Group1")); + await JobStore.PauseTriggers(GroupMatcher.GroupEndsWith("Group1")); //act - var resumedGroups = JobStore.ResumeTriggers(GroupMatcher.GroupEndsWith("Group1")); + var resumedGroups = await JobStore.ResumeTriggers(GroupMatcher.GroupEndsWith("Group1")); //assert Assert.IsTrue(resumedGroups.Count == 1); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger3.Key)); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger4.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger3.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger4.Key)); } /// /// resume all the trigger which their group contains foobar /// [TestMethod] - public void ResumeTrigger_UseContainsOperator_Successfully() + public async Task ResumeTrigger_UseContainsOperator_Successfully() { //arrange var job = CreateJob(); @@ -588,40 +594,40 @@ public void ResumeTrigger_UseContainsOperator_Successfully() var trigger3 = CreateTrigger("trigger3", "triggerfoobarGroup", job.Key); var trigger4 = CreateTrigger("trigger4", "triggerfoobarGroup", job.Key); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(trigger1, true); - JobStore.StoreTrigger(trigger2, true); - JobStore.StoreTrigger(trigger3, true); - JobStore.StoreTrigger(trigger4, true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(trigger1, true); + await JobStore.StoreTrigger(trigger2, true); + await JobStore.StoreTrigger(trigger3, true); + await JobStore.StoreTrigger(trigger4, true); - JobStore.PauseTriggers(GroupMatcher.GroupContains("foobar")); + await JobStore.PauseTriggers(GroupMatcher.GroupContains("foobar")); //act - var resumedGroups = JobStore.ResumeTriggers(GroupMatcher.GroupContains("foobar")); + var resumedGroups = await JobStore.ResumeTriggers(GroupMatcher.GroupContains("foobar")); //assert Assert.IsTrue(resumedGroups.Count == 1); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger3.Key)); - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger4.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger3.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger4.Key)); } /// /// get all the triggergroup whose state is in paused. /// [TestMethod] - public void GetPausedTriggerGroupsSuccessfully() + public async Task GetPausedTriggerGroupsSuccessfully() { //arrange var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key), true); - JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerGroup")); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key), true); + await JobStore.PauseTriggers(GroupMatcher.GroupEquals("triggerGroup")); //act - var pausedGroups = JobStore.GetPausedTriggerGroups(); + var pausedGroups = await JobStore.GetPausedTriggerGroups(); //Assert Assert.IsTrue(pausedGroups.Count == 1); @@ -631,21 +637,21 @@ public void GetPausedTriggerGroupsSuccessfully() /// Pause all the triggers in the store /// [TestMethod] - public void PauseAllSuccessfully() + public async Task PauseAllSuccessfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 2, 2, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); //act - JobStore.PauseAll(); + await JobStore.PauseAll(); //assert foreach (var jobAndTriggers in jobsAndTriggers) { foreach (var trigger in jobAndTriggers.Value) { - Assert.AreEqual(TriggerState.Paused, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Paused, await JobStore.GetTriggerState(trigger.Key)); } } @@ -655,22 +661,22 @@ public void PauseAllSuccessfully() /// Resume all the triggers in the store /// [TestMethod] - public void ResumeAll_AfterPauseAll_Successfully() + public async Task ResumeAll_AfterPauseAll_Successfully() { //arrange var jobsAndTriggers = CreateJobsAndTriggers(2, 1, 1, 2); - JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); - JobStore.PauseAll(); + await JobStore.StoreJobsAndTriggers(jobsAndTriggers, false); + await JobStore.PauseAll(); //act - JobStore.ResumeAll(); + await JobStore.ResumeAll(); //assert foreach (var jobAndTriggers in jobsAndTriggers) { foreach (var trigger in jobAndTriggers.Value) { - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); } } } @@ -679,26 +685,26 @@ public void ResumeAll_AfterPauseAll_Successfully() /// when acquireNextTriggers is called, the triggers returned are in the acquired state. /// [TestMethod] - public void AcquireNextTriggers_TriggersAreInAcquiredState_Successfully() + public async Task AcquireNextTriggers_TriggersAreInAcquiredState_Successfully() { //arrange var calendarName = "testCalendar1"; - JobStore.StoreCalendar(calendarName, new WeeklyCalendar(), true, true); + await JobStore.StoreCalendar(calendarName, new WeeklyCalendar(), true, true); var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key, "* * * * * ?", calendarName), true); //act - var acquiredTriggers = JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); + var acquiredTriggers = await JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); //assert Assert.IsTrue(acquiredTriggers.Count == 4); foreach (var trigger in acquiredTriggers) { - Assert.AreEqual(TriggerState.Normal, JobStore.GetTriggerState(trigger.Key)); + Assert.AreEqual(TriggerState.Normal, await JobStore.GetTriggerState(trigger.Key)); var triggerHashKey = Schema.TriggerHashkey(trigger.Key); Assert.IsTrue(Db.SortedSetScore(Schema.TriggerStateSetKey(RedisTriggerState.Acquired), triggerHashKey) > 0); } @@ -708,21 +714,21 @@ public void AcquireNextTriggers_TriggersAreInAcquiredState_Successfully() /// Trigger Firing /// [TestMethod] - public void TriggerFiredSuccessfully() + public async Task TriggerFiredSuccessfully() { //arrange var calendarName = "testCalendar10"; - JobStore.StoreCalendar(calendarName, new WeeklyCalendar(), true, true); + await JobStore.StoreCalendar(calendarName, new WeeklyCalendar(), true, true); var job = CreateJob(); - JobStore.StoreJob(job, true); - JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key, "* * * * * ?", calendarName), true); - JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key, "* * * * * ?", calendarName), true); - var acquiredTriggers = JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); + await JobStore.StoreJob(job, true); + await JobStore.StoreTrigger(CreateTrigger("trigger1", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger2", "triggerGroup", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger3", "triggerfoobarGroup1", job.Key, "* * * * * ?", calendarName), true); + await JobStore.StoreTrigger(CreateTrigger("trigger4", "triggerfoobarGroup2", job.Key, "* * * * * ?", calendarName), true); + var acquiredTriggers = await JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); //act - var triggerFiredResult = JobStore.TriggersFired(acquiredTriggers); + var triggerFiredResult = await JobStore.TriggersFired(acquiredTriggers); //assert Assert.IsTrue(triggerFiredResult.Count == 4); @@ -732,7 +738,7 @@ public void TriggerFiredSuccessfully() /// during firing a trigger, need to add the job which does allow concurrent execution into blockedJobSet in the store. /// [TestMethod] - public void TriggerFired_JobIsDisallowedConcurrent_AddToBlockedJobSet() + public async Task TriggerFired_JobIsDisallowedConcurrent_AddToBlockedJobSet() { //arrange var job = @@ -742,14 +748,14 @@ public void TriggerFired_JobIsDisallowedConcurrent_AddToBlockedJobSet() .Build(); var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key, "* * * * * ?","testCalendar33"); - JobStore.StoreCalendar("testCalendar33", new WeeklyCalendar(), true, true); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreCalendar("testCalendar33", new WeeklyCalendar(), true, true); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); var jobHashKey = Schema.JobHashKey(job.Key); - var acquiredTriggers = JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); + var acquiredTriggers = await JobStore.AcquireNextTriggers(new DateTimeOffset(DateTime.UtcNow), 20, TimeSpan.FromMilliseconds(1000)); //act - JobStore.TriggersFired(acquiredTriggers); + await JobStore.TriggersFired(acquiredTriggers); //assert Assert.IsTrue(Db.SetContains(Schema.BlockedJobsSet(), jobHashKey)); @@ -759,16 +765,16 @@ public void TriggerFired_JobIsDisallowedConcurrent_AddToBlockedJobSet() /// could not replace trigger, if the triggers are different in group. /// [TestMethod] - public void ReplaceTrigger_WithDifferentNameAndGroup_Unsuccessfully() + public async Task ReplaceTrigger_WithDifferentNameAndGroup_Unsuccessfully() { //arrange var job = CreateJob(); var trigger = CreateTrigger("testTrigger", "testTriggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger, false); //act - var result = JobStore.ReplaceTrigger(new TriggerKey("foo", "bar"), trigger); + var result = await JobStore.ReplaceTrigger(new TriggerKey("foo", "bar"), trigger); //assert Assert.IsFalse(result); @@ -778,64 +784,64 @@ public void ReplaceTrigger_WithDifferentNameAndGroup_Unsuccessfully() /// when the old trigger is replaced, then it should be removed from store as well. /// [TestMethod] - public void ReplaceTrigger_OldTriggerRemoved_Successfully() + public async Task ReplaceTrigger_OldTriggerRemoved_Successfully() { //arrange var job = CreateJob(); var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); var newTrigger = CreateTrigger("newTrigger", "triggerGroup", job.Key); //act - var result = JobStore.ReplaceTrigger(trigger1.Key, newTrigger); + var result = await JobStore.ReplaceTrigger(trigger1.Key, newTrigger); //assert Assert.IsTrue(result); - Assert.IsNull(JobStore.RetrieveTrigger(trigger1.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(trigger1.Key)); } /// /// when the old trigger is replaced, then the new trigger is saved in the store. /// [TestMethod] - public void ReplaceTrigger_NewTriggerAdded_Successfully() + public async Task ReplaceTrigger_NewTriggerAdded_Successfully() { //arrange var job = CreateJob(); var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); var trigger2 = CreateTrigger("trigger2", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); - JobStore.StoreTrigger(trigger2, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreTrigger(trigger2, false); var newTrigger = CreateTrigger("newTrigger", "triggerGroup", job.Key); //act - JobStore.ReplaceTrigger(trigger1.Key, newTrigger); + await JobStore.ReplaceTrigger(trigger1.Key, newTrigger); //assert - Assert.IsTrue(JobStore.GetTriggersForJob(job.Key).Count == 2); - Assert.IsTrue(JobStore.GetTriggersForJob(job.Key).Select(x => x.Key.Equals(newTrigger.Key)).Any()); + Assert.IsTrue((await JobStore.GetTriggersForJob(job.Key)).Count == 2); + Assert.IsTrue((await JobStore.GetTriggersForJob(job.Key)).Select(x => x.Key.Equals(newTrigger.Key)).Any()); } /// /// when a non durable job has a trigger, that trigger is replaced by a new trigger. the job will not be removed. /// [TestMethod] - public void RepaceTrigger_ForNonDurableJobWithSingleTrigger_JobStillExistsAfterTriggerReplacement() + public async Task RepaceTrigger_ForNonDurableJobWithSingleTrigger_JobStillExistsAfterTriggerReplacement() { //arrange var job = CreateJob("job11"); var trigger1 = CreateTrigger("trigger3", "triGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); var newTrigger = CreateTrigger("newTrigger", "triGroup", job.Key); //act - JobStore.ReplaceTrigger(trigger1.Key, newTrigger); - var result = JobStore.RetrieveJob(job.Key); + await JobStore.ReplaceTrigger(trigger1.Key, newTrigger); + var result = await JobStore.RetrieveJob(job.Key); //assert Assert.IsNotNull(result); @@ -845,18 +851,17 @@ public void RepaceTrigger_ForNonDurableJobWithSingleTrigger_JobStillExistsAfterT /// coulnt replace trigger if its for a dffernt job. /// [TestMethod, ExpectedException(typeof(JobPersistenceException))] - public void ReplaceTrigger_WithDifferentJob_Unsuccessfully() + public async Task ReplaceTrigger_WithDifferentJob_Unsuccessfully() { //arrange var job = CreateJob(); var trigger1 = CreateTrigger("trigger1", "triggerGroup", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); var newTrigger = CreateTrigger("newTrigger", "triggerGroup", new JobKey("foo", "bar")); //act - JobStore.ReplaceTrigger(trigger1.Key, newTrigger); - + await JobStore.ReplaceTrigger(trigger1.Key, newTrigger); } } } diff --git a/QuartzRedisJobStore.UnitTest/TriggerJobCompleteFixture.cs b/QuartzRedisJobStore.UnitTest/TriggerJobCompleteFixture.cs index e80e797..667f1e4 100644 --- a/QuartzRedisJobStore.UnitTest/TriggerJobCompleteFixture.cs +++ b/QuartzRedisJobStore.UnitTest/TriggerJobCompleteFixture.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Quartz; using Quartz.Impl; @@ -31,9 +32,9 @@ public void Initialize() _job = CreateJob(); _trigger1 = CreateTrigger("trigger1", "triggerGroup1", _job.Key); _trigger2 = CreateTrigger("trigger2", "triggerGroup1", _job.Key); - JobStore.StoreJob(_job, false); - JobStore.StoreTrigger(_trigger1, false); - JobStore.StoreTrigger(_trigger2, false); + JobStore.StoreJob(_job, false).Wait(); + JobStore.StoreTrigger(_trigger1, false).Wait(); + JobStore.StoreTrigger(_trigger2, false).Wait(); } /// @@ -43,7 +44,7 @@ public void Initialize() public void ClearAllJobStoreData() { System.Diagnostics.Debug.Write("here"); - JobStore?.ClearAllSchedulingData(); + JobStore?.ClearAllSchedulingData().Wait(); System.Diagnostics.Debug.Write(counter++); } @@ -57,66 +58,66 @@ public static void ClassCleanup() /// call TriggeredJobComplete, set Instruction to delete, trigger is deleted /// [TestMethod] - public void TrigggeredJobComplete_SetInstructionToDeleted_TriggerIsDeletedSuccesfully() + public async Task TrigggeredJobComplete_SetInstructionToDeleted_TriggerIsDeletedSuccesfully() { //act - JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.DeleteTrigger); + await JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.DeleteTrigger); //assert - Assert.IsNull(JobStore.RetrieveTrigger(_trigger1.Key)); + Assert.IsNull(await JobStore.RetrieveTrigger(_trigger1.Key)); - MockedSignaler.Verify(x => x.SignalSchedulingChange(null)); + MockedSignaler.Verify(x => x.SignalSchedulingChange(null, default)); } /// /// call triggeredJobCompelete, set Instruction to error, trigger is moved to the error state. /// [TestMethod] - public void TrigggeredJobComplete_SetInstructionToError_TriggerSetToErrorState() + public async Task TrigggeredJobComplete_SetInstructionToError_TriggerSetToErrorState() { //act - JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetTriggerError); + await JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetTriggerError); //assert - Assert.AreEqual(TriggerState.Error, JobStore.GetTriggerState(_trigger1.Key)); - MockedSignaler.Verify(x => x.SignalSchedulingChange(null)); + Assert.AreEqual(TriggerState.Error, await JobStore.GetTriggerState(_trigger1.Key)); + MockedSignaler.Verify(x => x.SignalSchedulingChange(null, default)); } /// /// call triggeredJobCompelete, set Instruction to allJobTriggersError, triggers are moved to the error state. /// [TestMethod] - public void TrigggeredJobComplete_SetInstructionToAllJobTriggersError_TriggersSetToErrorState() + public async Task TrigggeredJobComplete_SetInstructionToAllJobTriggersError_TriggersSetToErrorState() { //act - JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetAllJobTriggersError); + await JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetAllJobTriggersError); //assert - Assert.AreEqual(TriggerState.Error, JobStore.GetTriggerState(_trigger1.Key)); - Assert.AreEqual(TriggerState.Error, JobStore.GetTriggerState(_trigger2.Key)); - MockedSignaler.Verify(x => x.SignalSchedulingChange(null)); + Assert.AreEqual(TriggerState.Error, await JobStore.GetTriggerState(_trigger1.Key)); + Assert.AreEqual(TriggerState.Error, await JobStore.GetTriggerState(_trigger2.Key)); + MockedSignaler.Verify(x => x.SignalSchedulingChange(null, default)); } /// /// call triggeredJobCompelete, set Instruction to AllJobTriggersComplete, triggers are moved to the complete state. /// [TestMethod] - public void TrigggeredJobComplete_SetInstructionToAllJobTriggersComplete_TriggersSetoCompleteState() + public async Task TrigggeredJobComplete_SetInstructionToAllJobTriggersComplete_TriggersSetoCompleteState() { //act - JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetAllJobTriggersComplete); + await JobStore.TriggeredJobComplete(_trigger1, _job, SchedulerInstruction.SetAllJobTriggersComplete); //assert - Assert.AreEqual(TriggerState.Complete, JobStore.GetTriggerState(_trigger1.Key)); - Assert.AreEqual(TriggerState.Complete, JobStore.GetTriggerState(_trigger2.Key)); - MockedSignaler.Verify(x => x.SignalSchedulingChange(null)); + Assert.AreEqual(TriggerState.Complete, await JobStore.GetTriggerState(_trigger1.Key)); + Assert.AreEqual(TriggerState.Complete, await JobStore.GetTriggerState(_trigger2.Key)); + MockedSignaler.Verify(x => x.SignalSchedulingChange(null, default)); } /// /// check jobdatamap is persisted into store after the trigger completes. /// [TestMethod] - public void TriggeredJobComplete_JobIsPersist_JobDataMapIsResavedSuccessfully() + public async Task TriggeredJobComplete_JobIsPersist_JobDataMapIsResavedSuccessfully() { //arrange var job = @@ -126,26 +127,26 @@ public void TriggeredJobComplete_JobIsPersist_JobDataMapIsResavedSuccessfully() .WithDescription("I am a persist job") .Build(); - var trigger1 = CreateTrigger("trigger1", "triggerGroup1", _job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); + var trigger1 = CreateTrigger("trigger11", "triggerGroup11", _job.Key); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); var jobDetails = (JobDetailImpl)job; IDictionary dict = new Dictionary { { "test", "test" } }; jobDetails.JobDataMap = new JobDataMap(dict); //act - JobStore.TriggeredJobComplete(trigger1, job, SchedulerInstruction.SetTriggerComplete); - var retrievedJob = JobStore.RetrieveJob(job.Key); + await JobStore.TriggeredJobComplete(trigger1, job, SchedulerInstruction.SetTriggerComplete); + var retrievedJob = await JobStore.RetrieveJob(job.Key); //assert - Assert.AreEqual(retrievedJob.JobDataMap["test"], "test"); + Assert.AreEqual("test", retrievedJob.JobDataMap["test"]); } /// /// when trigger completes, the disallow concurrent execution job should be removed from blockedJobsSet. /// [TestMethod] - public void TriggeredJobComplete_ForDisallowConcurrentJob_JobIsNotInBlockedJobsSet() + public async Task TriggeredJobComplete_ForDisallowConcurrentJob_JobIsNotInBlockedJobsSet() { //arrange var job = @@ -154,14 +155,13 @@ public void TriggeredJobComplete_ForDisallowConcurrentJob_JobIsNotInBlockedJobsS .WithDescription("I am a DisallowConcurrent job") .Build(); - var trigger1 = CreateTrigger("trigger1", "triggerGroup1", job.Key); - JobStore.StoreJob(job, false); - JobStore.StoreTrigger(trigger1, false); + var trigger1 = CreateTrigger("trigger11", "triggerGroup11", job.Key); + await JobStore.StoreJob(job, false); + await JobStore.StoreTrigger(trigger1, false); var jobHashKey = Schema.JobHashKey(job.Key); //act - JobStore.TriggeredJobComplete(trigger1, job, SchedulerInstruction.SetTriggerComplete); - + await JobStore.TriggeredJobComplete(trigger1, job, SchedulerInstruction.SetTriggerComplete); //assert Assert.IsFalse(Db.SetContains(Schema.BlockedJobsSet(), jobHashKey)); diff --git a/QuartzRedisJobStore.UnitTest/packages.config b/QuartzRedisJobStore.UnitTest/packages.config index c9fb6f5..ddd28bb 100644 --- a/QuartzRedisJobStore.UnitTest/packages.config +++ b/QuartzRedisJobStore.UnitTest/packages.config @@ -2,8 +2,25 @@ + + + + - - - + + + + + + + + + + + + + + + + \ No newline at end of file