public ScheduledTaskAsyncCallback Wrap(ScheduledTaskCallback callback, Func<ScheduledTask, DateTimeOffset, bool> shouldTryToRun = null) { if (callback == null) throw new ArgumentNullException(nameof(callback)); return GetWrappedCallback(callback, null, shouldTryToRun); }
public ScheduledTask AddScheduledTask(double interval, ScheduledTaskCallback callback) { ScheduledTask task = new ScheduledTask(); task.Interval = interval; task.Callback = callback; Tasks.Add(task); return(task); }
public ScheduledTaskAsyncCallback Wrap(ScheduledTaskCallback callback, Func <ScheduledTask, DateTimeOffset, bool> shouldTryToRun = null) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(GetWrappedCallback(callback, null, shouldTryToRun)); }
private static ScheduledTask[] AddTaskMulti(string name, string schedule, Combo[] combos, ScheduledTaskCallback callback) { var tasks = new ScheduledTask[combos.Length]; for (var i = 0; i < combos.Length; i++) { var schtick = combos[i].Schtick; var wrapper = combos[i].Wrapper; tasks[i] = schtick.AddAsyncTask(name, schedule, wrapper.Wrap(callback)); } return tasks; }
ScheduledTask AddTaskImpl( string name, Schedule schedule, ScheduledTaskCallback callback, ScheduledTaskAsyncCallback asyncCallback, bool autoRun, DateTimeOffset lastKnownEvent, TimeSpan window) { if (schedule == null) { throw new ArgumentNullException(nameof(schedule)); } if (name == null) { name = Guid.NewGuid().ToString(); } ScheduledTask task; lock (_lockTasks) { if (IsShuttingDown) { throw new Exception("Cannot add a task to Schtick after Shutdown() has been called."); } if (_tasks.ContainsKey(name)) { throw new Exception($"A scheduled task named \"{name}\" already exists."); } task = new ScheduledTask(this, name, schedule, callback, asyncCallback) { Window = window, IsAttached = true, }; _tasks.Add(name, task); } task.OnException += TaskOnOnException; if (autoRun) { task.StartSchedule(lastKnownEvent); } return(task); }
internal ScheduledTask(Schtick schtick, string name, Schedule schedule, ScheduledTaskCallback callback, ScheduledTaskAsyncCallback asyncCallback) { _schtick = schtick; Name = name; Schedule = schedule; if ((callback == null) == (asyncCallback == null)) { throw new Exception("callback or asyncCallback must be specified, but not both."); } Callback = callback; AsyncCallback = asyncCallback; }
/// <summary> /// Adds a scheduled task to this instance of Schtick. /// </summary> /// <param name="name">A unique name for this task. If null, a guid will be used.</param> /// <param name="schedule">A Schyntax Schedule object.</param> /// <param name="callback">Function which will be called each time the task is supposed to run.</param> /// <param name="autoRun">If true, Start() will be called on the task automatically.</param> /// <param name="lastKnownEvent">The last Date when the task is known to have run. Used for Task Windows.</param> /// <param name="window"> /// The period of time after an event should have run where it would still be appropriate to run it. /// See Task Windows documentation for more details. /// </param> public ScheduledTask AddTask( string name, Schedule schedule, ScheduledTaskCallback callback, bool autoRun = true, DateTimeOffset lastKnownEvent = default(DateTimeOffset), TimeSpan window = default(TimeSpan)) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(AddTaskImpl(name, schedule, callback, null, autoRun, lastKnownEvent, window)); }
/// <summary> /// Adds a scheduled task to this instance of Schtick. /// </summary> /// <param name="name">A unique name for this task. If null, a guid will be used.</param> /// <param name="schedule">A Schyntax schedule string.</param> /// <param name="callback">Function which will be called each time the task is supposed to run.</param> /// <param name="autoRun">If true, Start() will be called on the task automatically.</param> /// <param name="lastKnownEvent">The last Date when the task is known to have run. Used for Task Windows.</param> /// <param name="window"> /// The period of time after an event should have run where it would still be appropriate to run it. /// See Task Windows documentation for more details. /// </param> public ScheduledTask AddTask( string name, string schedule, ScheduledTaskCallback callback, bool autoRun = true, DateTimeOffset lastKnownEvent = default(DateTimeOffset), TimeSpan window = default(TimeSpan)) { if (schedule == null) throw new ArgumentNullException(nameof(schedule)); if (callback == null) throw new ArgumentNullException(nameof(callback)); return AddTaskImpl(name, new Schedule(schedule), callback, null, autoRun, lastKnownEvent, window); }
private ScheduledTaskAsyncCallback GetWrappedCallback( ScheduledTaskCallback originalCallback, ScheduledTaskAsyncCallback originalAsyncCallback, Func <ScheduledTask, DateTimeOffset, bool> shouldTryToRun) { var host = _machineName; var lastKey = _lastKey; return(async(task, timeIntendedToRun) => { if (shouldTryToRun?.Invoke(task, timeIntendedToRun) == false) { return; } var iso = timeIntendedToRun.ToString("o"); RedisKey lockKey = _keyPrefix + ";" + task.Name + ";" + iso; var lastLockValue = iso + ";" + DateTimeOffset.UtcNow.ToString("o") + ";" + host; // set the redis lock for one hour longer than the window var window = task.Window; var expiry = (window > TimeSpan.Zero ? window : TimeSpan.Zero) + TimeSpan.FromHours(1); var px = expiry.TotalMilliseconds; // see if we can get the lock on this task var db = _getRedisDb(); var name = task.Name; var lockAcquired = await db.ScriptEvaluateAsync( s_redisLockScript, new { lockKey, host, px, lastKey, name, lastLockValue }, flags : CommandFlags.DemandMaster ).ConfigureAwait(false); if ((int)lockAcquired == 1) { // we got the lock, now run the task if (originalCallback != null) { originalCallback(task, timeIntendedToRun); } else { await originalAsyncCallback(task, timeIntendedToRun).ConfigureAwait(false); } } }); }
private static ScheduledTask[] AddTaskMulti(string name, string schedule, Combo[] combos, ScheduledTaskCallback callback) { var tasks = new ScheduledTask[combos.Length]; for (var i = 0; i < combos.Length; i++) { var schtick = combos[i].Schtick; var wrapper = combos[i].Wrapper; tasks[i] = schtick.AddAsyncTask(name, schedule, wrapper.Wrap(callback)); } return(tasks); }
internal ScheduledTask(Schtick schtick, string name, Schedule schedule, ScheduledTaskCallback callback, ScheduledTaskAsyncCallback asyncCallback) { _schtick = schtick; Name = name; Schedule = schedule; if ((callback == null) == (asyncCallback == null)) throw new Exception("callback or asyncCallback must be specified, but not both."); Callback = callback; AsyncCallback = asyncCallback; }
private ScheduledTask AddTaskImpl( string name, Schedule schedule, ScheduledTaskCallback callback, ScheduledTaskAsyncCallback asyncCallback, bool autoRun, DateTimeOffset lastKnownEvent, TimeSpan window) { if (schedule == null) throw new ArgumentNullException(nameof(schedule)); if (name == null) name = Guid.NewGuid().ToString(); ScheduledTask task; lock (_lockTasks) { if (IsShuttingDown) throw new Exception("Cannot add a task to Schtick after Shutdown() has been called."); if (_tasks.ContainsKey(name)) throw new Exception($"A scheduled task named \"{name}\" already exists."); task = new ScheduledTask(this, name, schedule, callback, asyncCallback) { Window = window, IsAttached = true, }; _tasks.Add(name, task); } task.OnException += TaskOnOnException; if (autoRun) task.StartSchedule(lastKnownEvent); return task; }
private ScheduledTaskAsyncCallback GetWrappedCallback( ScheduledTaskCallback originalCallback, ScheduledTaskAsyncCallback originalAsyncCallback, Func<ScheduledTask, DateTimeOffset, bool> shouldTryToRun) { var host = _machineName; var lastKey = _lastKey; return async (task, timeIntendedToRun) => { if (shouldTryToRun?.Invoke(task, timeIntendedToRun) == false) return; var iso = timeIntendedToRun.ToString("o"); RedisKey lockKey = _keyPrefix + ";" + task.Name + ";" + iso; var lastLockValue = iso + ";" + DateTimeOffset.UtcNow.ToString("o") + ";" + host; // set the redis lock for one hour longer than the window var window = task.Window; var expiry = (window > TimeSpan.Zero ? window : TimeSpan.Zero) + TimeSpan.FromHours(1); var px = expiry.TotalMilliseconds; // see if we can get the lock on this task var db = _getRedisDb(); var name = task.Name; var lockAcquired = await db.ScriptEvaluateAsync( s_redisLockScript, new { lockKey, host, px, lastKey, name, lastLockValue }, flags: CommandFlags.DemandMaster ).ConfigureAwait(false); if ((int)lockAcquired == 1) { // we got the lock, now run the task if (originalCallback != null) originalCallback(task, timeIntendedToRun); else await originalAsyncCallback(task, timeIntendedToRun).ConfigureAwait(false); } }; }