/// <summary> /// Determine whether a new task needs to be executed /// </summary> /// <param name="type">Type</param> /// <returns>True if need to execute, false if not</returns> public virtual async Task <bool> Check(Type type) { if (null == type) { throw new ArgumentNullException("type"); } var entry = new ScheduledTaskEntry() { PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()), ServiceName = type.GetType().ToString(), }; var performTask = true; var records = await this.storage.QueryByPartition <ScheduledTaskEntry>(entry.PartitionKey); if (records != null && records.Any()) { var latest = records.OrderByDescending(x => x.StartTime).First(); performTask = (latest.CompletionTime.HasValue) ? DateTime.UtcNow.Subtract(latest.CompletionTime.Value) >= period || !latest.Successful : DateTime.UtcNow.Subtract(latest.StartTime) >= retryInterval; } return(performTask); }
/// <summary> /// Determine whether a new task needs to be executed /// </summary> /// <param name="entry">Scheduled Task Entry</param> /// <returns>True if need to execute, false if not</returns> public bool CheckForTask(ScheduledTaskEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } var performTask = true; Trace.WriteLine(string.Format("{0} [{1}] Querying scheduled tasks table for the latest task.", DateTime.UtcNow, entry.ServiceName)); // Peek the table first to determine if there's any task to execute // Query the table by partition key (type, year, month) var records = base.QueryByPartition <ScheduledTaskEntry>(entry.PartitionKey); if (records != null && records.Count() > 0) { var latest = records.OrderByDescending(x => x.StartTime).First(); Trace.WriteLine(string.Format("{0} [{1}] Latest task found in table: Partition: {2} Id: {3} StartTime: {4} CompletionTime: {5}", DateTime.UtcNow, entry.ServiceName, latest.PartitionKey, latest.Identifier, latest.StartTime, latest.CompletionTime)); // 1. If the latest task has been completed, then perform task if // - the latest task has been completed more than <period> ago, or // - the latest task was unsuccessful // 2. If the latest task has been started but not completed yet, // then perform the task if it has been started more than <backupRetryInterval> ago performTask = (latest.CompletionTime.HasValue) ? DateTime.UtcNow.Subtract(latest.CompletionTime.Value) >= period || !latest.Successful : DateTime.UtcNow.Subtract(latest.StartTime) >= retryInterval; } return(performTask); }
/// <summary> /// Execute /// </summary> /// <param name="state">State</param> protected override async void Execute(object state) { var startTime = DateTime.UtcNow; var completionTime = DateTime.UtcNow; var entry = new ScheduledTaskEntry(this.GetType().ToString()); Trace.WriteLine(string.Format("{0} [{1}] Task Checking.", startTime, entry.ServiceName)); try { if (taskCore.CheckForTask(entry)) { Trace.WriteLine(string.Format("{0} [{1}] Task Started.", DateTime.UtcNow, entry.ServiceName)); // Insert a new backup entry to table entry.Identifier = Guid.NewGuid(); entry.StartTime = DateTime.UtcNow; await taskCore.InsertOrReplace(entry); try { this.Execute(); entry.Successful = true; } catch (Exception ex) { Trace.TraceError(string.Format("{0}:{1}", this.GetType(), ex.Message)); entry.Successful = false; } finally { entry.CompletionTime = DateTime.UtcNow; } // Update entry in table await taskCore.InsertOrReplace(entry); } else { Trace.WriteLine(string.Format("{0} [{1}] No Action Required.", DateTime.UtcNow, entry.ServiceName)); } } catch (Exception ex) { Trace.TraceError(string.Format("{0}:{1}", this.GetType(), ex.Message)); entry.Successful = false; } finally { completionTime = DateTime.UtcNow; } Trace.WriteLine(string.Format("{0} [{1}] Task Completed. Success: {2}", DateTime.UtcNow, entry.ServiceName, entry.Successful)); }
public void ServiceName() { var expected = ScheduledTaskEntry.GenerateLogsPartitionKey(this.GetType().ToString()); var entity = new ScheduledTaskEntry { ServiceName = expected, }; Assert.AreEqual(expected, entity.ServiceName); }
public void Identifier() { var entity = new ScheduledTaskEntry { PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(this.GetType().ToString()), ServiceName = this.GetType().ToString(), }; Assert.IsNull(entity.Identifier); var data = Guid.NewGuid(); entity.Identifier = data; Assert.AreEqual(data, entity.Identifier); entity.Identifier = null; Assert.IsNull(entity.Identifier); }
/// <summary> /// Complete /// </summary> /// <param name="type">Task Type</param> /// <param name="identifier">Identifier</param> /// <param name="start">Start</param> /// <param name="end">End</param> /// <param name="success">Success</param> /// <returns>Task</returns> public virtual async Task Complete(Type type, Guid identifier, DateTime start, DateTime end, bool success) { if (null == type) { throw new ArgumentNullException("type"); } await this.storage.InsertOrReplace(new ScheduledTaskEntry { PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()), ServiceName = type.GetType().ToString(), Identifier = Guid.Empty == identifier ? Guid.NewGuid() : identifier, StartTime = start, CompletionTime = end, Successful = success, }); }
/// <summary> /// Start /// </summary> /// <param name="type">Task Type</param> /// <param name="identifier">Identifier</param> /// <param name="start">Start</param> /// <returns>Task</returns> public virtual async Task Start(Type type, Guid identifier, DateTime start) { if (null == type) { throw new ArgumentNullException("type"); } if (Guid.Empty == identifier) { throw new ArgumentException("identifier"); } await this.storage.InsertOrReplace(new ScheduledTaskEntry { PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()), ServiceName = type.GetType().ToString(), Identifier = identifier, StartTime = start, }); }
internal ScheduledTaskAccessCheckResult(ScheduledTaskEntry entry, AccessMask granted_access, SecurityDescriptor sd, GenericMapping generic_mapping, TokenInformation token_info) : base(entry.Path, GetAccessibleScheduledTaskCmdlet.TypeName, granted_access, generic_mapping, sd, typeof(FileAccessRights), false, token_info) { Enabled = entry.Enabled; Hidden = entry.Hidden; AllowDemandStart = entry.AllowDemandStart; Xml = entry.Xml; LogonType = entry.LogonType; RunLevel = entry.RunLevel; Principal = entry.Principal; Actions = entry.Actions; ActionCount = Actions.Count(); RequiredPrivileges = entry.RequiredPrivilege; ProcessTokenSid = entry.ProcessTokenSid; HasActionArguments = entry.HasActionArguments; }
public async Task Check() { var records = new List <ScheduledTaskEntry>(); var record = new ScheduledTaskEntry() { StartTime = DateTime.UtcNow.AddHours(-1), CompletionTime = null, }; records.Add(record); var table = Substitute.For <ITableStorage>(); table.QueryByPartition <ScheduledTaskEntry>(Arg.Any <string>()).Returns(Task.FromResult <IEnumerable <ScheduledTaskEntry> >(records)); var core = new Coordinator(table, TimeSpan.FromSeconds(1)); var perform = await core.Check(this.GetType()); Assert.IsTrue(perform); table.Received().QueryByPartition <ScheduledTaskEntry>(Arg.Any <string>()); }
public void GenerateLogsPartitionKey() { var serviceName = Guid.NewGuid().ToString(); Assert.AreEqual(string.Format("{0}-{1:yyyy}-{1:MM}", serviceName, DateTime.UtcNow), ScheduledTaskEntry.GenerateLogsPartitionKey(serviceName)); }