private void ValidateTask(ScheduledTask task) { if(String.IsNullOrEmpty(task.Name)) throw new ArgumentException("Task name is required.", "task"); if(task.BindingType == null) throw new ArgumentException("Task binding type is required.", "task"); if(task.EndpointAddress == null) throw new ArgumentException("Task endpoint address is required.", "task"); }
public void CalculateNextRunTimeTest() { var task = new ScheduledTask { StartDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, 0, 0).ToUniversalTime(), RepeatInterval = TimeSpan.FromMinutes(60), }; task.NextRunTime = TaskCalculator.CalculateNextRunTime(task); var expectedTime = task.StartDate.AddHours(1); Assert.That(task.NextRunTime, Is.EqualTo(expectedTime)); }
public void Save(ScheduledTask task) { ValidateTask(task); var element = new XDocument(); using(var writer = element.CreateWriter()) new DataContractSerializer(typeof(ScheduledTask)).WriteObject(writer, task); element.Root.RemoveAttributes(); var document = LoadXml(); var existing = document.Elements().FirstOrDefault(x => x.Element(XName.Get("Name", "http://schemas.datacontract.org/2004/07/Pendulum")).Value == task.Name); if(existing == null) document.Add(element.Root); else existing.ReplaceWith(element.Root); document.Save(FileName); }
public void CalculateNextRetryTime() { var task = new ScheduledTask { StartDate = new DateTime(2000, 5, 16, DateTime.Now.Hour, 0, 0).ToUniversalTime(), RepeatInterval = TimeSpan.FromMinutes(60), RetryInterval = TimeSpan.FromMinutes(10), }; task.NextRunTime = TaskCalculator.CalculateNextRetryTime(task); var expectedTime = DateTime.UtcNow.AddMinutes(10); Assert.That(task.NextRunTime, Is.InRange(expectedTime.AddMinutes(-1), expectedTime.AddMinutes(1))); }
private ScheduledTaskClient CreateClient(ScheduledTask task) { try { var binding = (Binding)Activator.CreateInstance(Type.GetType(task.BindingType)); binding.SendTimeout = task.SendTimeout; binding.ReceiveTimeout = task.ReceiveTimeout; var endpoint = new EndpointAddress(task.EndpointAddress); return new ScheduledTaskClient(binding, endpoint); } catch(Exception ex) { RecordResult(task, TaskResult.FatalError, "Error creating client proxy", ex); throw; } }
public void CalculateNextRunTimeAfterRetry() { var task = new ScheduledTask { StartDate = new DateTime(2000, 5, 16, DateTime.Now.Hour, 0, 0).ToUniversalTime(), RepeatInterval = TimeSpan.FromMinutes(60), RetryInterval = TimeSpan.FromMinutes(10), }; task.NextRunTime = TaskCalculator.CalculateNextRetryTime(task); task.NextRunTime = TaskCalculator.CalculateNextRunTime(task); var expectedTime = new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour + 1, 0, 0).ToUniversalTime(); Assert.That(task.NextRunTime, Is.EqualTo(expectedTime)); }
public void Execute(ScheduledTask task, ThreadController controller) { controller.Wait(); task.Status = TaskStatus.Running; _repository.Save(task); var client = CreateClient(task); controller.Wait(); try { client.Open(); var result = client.Execute(); client.Close(); RecordResult(task, result.Result, result.Message); } catch(TimeoutException te) { RecordResult(task, TaskResult.RecoverableFault, te.Message, te); client.Abort(); } catch(CommunicationException ce) { RecordResult(task, TaskResult.RecoverableFault, ce.Message, ce); client.Abort(); } catch(Exception ex) { RecordResult(task, TaskResult.FatalError, ex.Message, ex); client.Abort(); throw; } }
public void Execute(ScheduledTask task, ThreadController controller) { controller.Wait(); task.Status = TaskStatus.Running; _repository.Save(task); var client = CreateClient(task); controller.Wait(); try { client.Open(); var result = client.Execute(); client.Close(); RecordResult(task, result.Result, result.Message); } catch (TimeoutException te) { RecordResult(task, TaskResult.RecoverableFault, te.Message, te); client.Abort(); } catch (CommunicationException ce) { RecordResult(task, TaskResult.RecoverableFault, ce.Message, ce); client.Abort(); } catch (Exception ex) { RecordResult(task, TaskResult.FatalError, ex.Message, ex); client.Abort(); throw; } }
public static TimeSpan CalculateRandomDelay(ScheduledTask task) { var random = new Random().NextDouble(); return(TimeSpan.FromTicks((long)(random * task.RandomDelay.Ticks * 2) - task.RandomDelay.Ticks)); }
public static DateTime CalculateNextRunTime(ScheduledTask task) { return(task.StartDate + TimeSpan.FromTicks(((((DateTime.UtcNow - task.StartDate).Ticks / task.RepeatInterval.Ticks) + 1) * task.RepeatInterval.Ticks)) + CalculateRandomDelay(task)); }
public static TimeSpan CalculateRandomDelay(ScheduledTask task) { var random = new Random().NextDouble(); return TimeSpan.FromTicks((long)(random * task.RandomDelay.Ticks * 2) - task.RandomDelay.Ticks); }
public static DateTime CalculateNextRetryTime(ScheduledTask task) { return(DateTime.UtcNow + task.RetryInterval + CalculateRandomDelay(task)); }
public static DateTime CalculateNextRetryTime(ScheduledTask task) { return DateTime.UtcNow + task.RetryInterval + CalculateRandomDelay(task); }
public void CalculateNextRunTimeTest_RandomDelay() { var task = new ScheduledTask { StartDate = new DateTime(2000, 5, 16, DateTime.Now.Hour, 0, 0).ToUniversalTime(), RepeatInterval = TimeSpan.FromMinutes(60), RandomDelay = TimeSpan.FromMinutes(10), }; task.NextRunTime = TaskCalculator.CalculateNextRunTime(task); var expectedTime = new DateTime( DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour + 1, 0, 0).ToUniversalTime(); Console.WriteLine(task.NextRunTime.ToLocalTime()); Assert.That(task.NextRunTime, Is.InRange(expectedTime.AddMinutes(-10), expectedTime.AddMinutes(10))); }
private void RecordResult(ScheduledTask task, TaskResult result, string message, Exception exception = null) { if(exception != null) message += Environment.NewLine + Environment.NewLine + exception.Message + Environment.NewLine + Environment.NewLine + exception.StackTrace; switch(result) { case TaskResult.Success: task.RetryCount = 0; task.Status = TaskStatus.Ready; task.NextRunTime = TaskCalculator.CalculateNextRunTime(task); break; case TaskResult.RecoverableFault: if(task.RetryCount >= task.MaxRetryCount) goto case TaskResult.FatalError; task.RetryCount += 1; task.Status = TaskStatus.Retrying; task.NextRunTime = TaskCalculator.CalculateNextRetryTime(task); break; case TaskResult.FatalError: task.IsEnabled = false; task.RetryCount += 1; task.Status = TaskStatus.Faulted; break; } task.History.Add(new ScheduledTaskExecution { Message = message, Result = result, RunTime = DateTime.UtcNow, }); _repository.Save(task); }
public void CalculateRandomDelay() { var task = new ScheduledTask { StartDate = new DateTime(2000, 5, 16, DateTime.Now.Hour, 30, 22).ToUniversalTime(), RepeatInterval = TimeSpan.FromMinutes(15), RetryInterval = TimeSpan.FromMinutes(10), RandomDelay = TimeSpan.FromMinutes(10), }; for(var i = 0; i < 100; i++) { var delay = TaskCalculator.CalculateRandomDelay(task); System.Threading.Thread.Sleep(1); Console.WriteLine(delay); Assert.That(delay, Is.InRange(-task.RandomDelay, task.RandomDelay)); } }
public static DateTime CalculateNextRunTime(ScheduledTask task) { return task.StartDate + TimeSpan.FromTicks(((((DateTime.UtcNow - task.StartDate).Ticks / task.RepeatInterval.Ticks) + 1) * task.RepeatInterval.Ticks)) + CalculateRandomDelay(task); }