/// <inheritdoc /> public void Complete(Guid taskId, DateTime timestampUtc) { Trace.WriteLine("ENTER: Record task '{0}' completed ...".FormatInvariant(taskId)); string taskIdAsString = RedisConverter.ToString(taskId); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskIdAsString); RedisTaskRuntimeInfo taskInfo = this.GetById(taskId, false); taskInfo.Percentage = 100; taskInfo.Status = TaskStatus.Success; taskInfo.CompletedUtc = timestampUtc; byte[] content = this.serializer.Serialize(taskInfo); using (IRedisTransaction transaction = this.Provider.CreateTransaction()) { transaction.RemoveKey(entityKey); transaction.RemoveFromList(RedisTaskRuntimeInfoRepository.ActiveTasksList, taskIdAsString); transaction.SetHashValue(RedisTaskRuntimeInfoRepository.ArchiveTasksHash, taskIdAsString, content); transaction.Commit(); } Trace.WriteLine("EXIT: Task '{0}' completed recorded.".FormatInvariant(taskId)); }
private RedisTaskRuntimeInfo GetById(Guid taskId, bool fromArchive) { string taskIdAsString = RedisConverter.ToString(taskId); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskIdAsString); if (fromArchive) { byte[] content = this.provider.GetHashBinaryValue(RedisTaskRuntimeInfoRepository.ArchiveTasksHash, taskIdAsString); if (content == null) { return(null); } return((RedisTaskRuntimeInfo)this.serializer.Deserialize(content, typeof(RedisTaskRuntimeInfo))); } else { IReadOnlyDictionary <string, string> values = this.provider.GetHashAsText(entityKey); if (values.Count == 0) { return(null); } return(RedisTaskRuntimeInfoRepository.Convert(values)); } }
/// <inheritdoc /> public void Fail(Guid taskId, DateTime timestampUtc, Exception error) { if (error == null) { throw new ArgumentNullException(nameof(error)); } Trace.WriteLine("ENTER: Record task '{0}' failed with error '{1}' ...".FormatInvariant(taskId, error.Message)); string taskIdAsString = RedisConverter.ToString(taskId); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskIdAsString); RedisTaskRuntimeInfo taskInfo = this.GetById(taskId, false); taskInfo.Status = TaskStatus.Failed; taskInfo.CompletedUtc = timestampUtc; taskInfo.Error = error.ToString(); byte[] content = this.serializer.Serialize(taskInfo); using (IRedisTransaction transaction = this.Provider.CreateTransaction()) { transaction.RemoveKey(entityKey); transaction.RemoveFromList(RedisTaskRuntimeInfoRepository.ActiveTasksList, taskIdAsString); transaction.AddToList(RedisTaskRuntimeInfoRepository.FailedTasksList, taskIdAsString); transaction.SetHashValue(RedisTaskRuntimeInfoRepository.ArchiveTasksHash, taskIdAsString, content); transaction.Commit(); } Trace.WriteLine("EXIT: Task '{0}' failed with error '{1}' recorded.".FormatInvariant(taskId, error.Message)); }
/// <inheritdoc /> public void Assign(Guid taskId, Guid?taskProcessorId) { Trace.WriteLine("ENTER: Recording task '{0}' assigned to processor '{1}' ...".FormatInvariant(taskId, taskProcessorId)); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskId); this.Provider.SetHashValue(entityKey, "TaskProcessorId", RedisConverter.ToString(taskProcessorId)); Trace.WriteLine("EXIT: Task '{0}' assigned to processor '{1}' recorded.".FormatInvariant(taskId, taskProcessorId)); }
/// <inheritdoc /> public bool CheckIsPendingOrActive(Guid taskId) { Trace.WriteLine("ENTER: Checking if task '{0}' is pending or active ...".FormatInvariant(taskId)); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskId); bool result = this.provider.ContainsKey(entityKey); Trace.WriteLine("EXIT: Check whether task '{0}' is pending or active completed. Result is {1}.".FormatInvariant(taskId, result)); return(result); }
/// <inheritdoc /> public void Progress(Guid taskId, double percentage) { Trace.WriteLine("ENTER: Record task '{0}' progress to {1}% ...".FormatInvariant(taskId, percentage)); if ((percentage < 0) || (percentage > 100)) { throw new ArgumentOutOfRangeException("percentage"); } string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskId); this.Provider.SetHashValue(entityKey, "Percentage", RedisConverter.ToString(percentage)); Trace.WriteLine("ENTER: Task '{0}' progress to {1}% recorded.".FormatInvariant(taskId, percentage)); }
private Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> > GetAllByType(params string[] listKeys) { List <string> entityIds = new List <string>(); using (IRedisPipeline pipeline = this.provider.CreatePipeline()) { foreach (string listKey in listKeys) { pipeline.GetList(listKey, values => entityIds.AddRange(values)); } pipeline.Flush(); } Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> > result = new Dictionary <TaskStatus, IEnumerable <ITaskRuntimeInfo> >(); using (IRedisPipeline pipeline = this.provider.CreatePipeline()) { foreach (string entityId in entityIds) { string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(entityId); pipeline.GetHash(entityKey, values => { if (values.Count > 0) { ITaskRuntimeInfo taskInfo = RedisTaskRuntimeInfoRepository.Convert(values); IEnumerable <ITaskRuntimeInfo> collection; if (!result.TryGetValue(taskInfo.Status, out collection)) { collection = new List <ITaskRuntimeInfo>(); result.Add(taskInfo.Status, collection); } ((ICollection <ITaskRuntimeInfo>)collection).Add(taskInfo); } }); } pipeline.Flush(); } return(result); }
/// <inheritdoc /> public void Add(ITaskRuntimeInfo taskInfo) { if (taskInfo == null) { throw new ArgumentNullException("taskInfo"); } Trace.WriteLine("ENTER: Adding runtime information for task '{0}' of type '{1}' with priority '{2}' in polling queue '{3}' ...".FormatInvariant(taskInfo.TaskId, taskInfo.TaskType, taskInfo.Priority, taskInfo.PollingQueue)); taskInfo.ValidateForAdd(); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskInfo.TaskId); string addToListKey; Dictionary <string, string> values = new Dictionary <string, string>() { { "Id", RedisConverter.ToString(taskInfo.TaskId) }, { "TaskType", RedisConverter.ToString(taskInfo.TaskType, true) }, { "SubmittedUtc", RedisConverter.ToString(taskInfo.SubmittedUtc) }, { "Status", RedisConverter.ToString(taskInfo.Status) } }; if (string.IsNullOrEmpty(taskInfo.PollingQueue)) { values.Add("Priority", RedisConverter.ToString(taskInfo.Priority)); addToListKey = RedisTaskRuntimeInfoRepository.PendingTasksList; } else { values.Add("PollingQueue", taskInfo.PollingQueue); addToListKey = RedisTaskRuntimeInfoRepository.GetPollingQueueRedisKey(taskInfo.PollingQueue, TaskStatus.Pending); } using (IRedisTransaction transaction = this.Provider.CreateTransaction()) { transaction.SetHashValues(entityKey, values); transaction.AddToList(addToListKey, RedisConverter.ToString(taskInfo.TaskId)); transaction.Commit(); } Trace.WriteLine("EXIT: Runtime information for task '{0}' of type '{1}' with priority '{2}' in polling queue '{3}' added.".FormatInvariant(taskInfo.TaskId, taskInfo.TaskType, taskInfo.Priority, taskInfo.PollingQueue)); }
/// <inheritdoc /> public Type GetTaskType(Guid taskId) { Trace.WriteLine("ENTER: Getting task '{0}' type ...".FormatInvariant(taskId)); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskId); string taskTypeAsString = this.provider.GetHashTextValue(entityKey, "TaskType"); Type result = null; if (!string.IsNullOrEmpty(taskTypeAsString)) { #if DEBUG result = Type.GetType(taskTypeAsString, true); #else result = Type.GetType(taskTypeAsString, false); if (result == null) { Trace.TraceWarning("EXIT: Task '{0}' type '{1}' cannot be resolved.", taskId, taskTypeAsString); return(null); } #endif } else { RedisTaskRuntimeInfo taskInfo = this.GetById(taskId, true); if (taskInfo != null) { result = taskInfo.TaskType; } } if (result == null) { Trace.WriteLine("EXIT: Task '{0}' type was not found neither in hash nor in archive.".FormatInvariant(taskId)); } else { Trace.WriteLine("EXIT: Return task '{0}' type '{1}'.".FormatInvariant(taskId, result)); } return(result); }
/// <inheritdoc /> public IEnumerable <ITaskRuntimeInfo> ReservePollingQueueTasks(string pollingQueueKey, int maxResults) { Trace.WriteLine("ENTER: Reserving {0} polling queue '{1}' tasks for execution ...".FormatInvariant(maxResults, pollingQueueKey)); if (string.IsNullOrEmpty(pollingQueueKey)) { throw new ArgumentNullException(nameof(pollingQueueKey)); } if (maxResults < 0) { throw new ArgumentOutOfRangeException(nameof(maxResults), maxResults, "Value must not be negative."); } string pollingQueueListKey = RedisTaskRuntimeInfoRepository.GetPollingQueueRedisKey(pollingQueueKey, TaskStatus.Pending); List <string> entityIds = new List <string>(); using (IRedisPipeline pipeline = this.provider.CreatePipeline()) { for (int i = 0; i < maxResults; i++) { pipeline.PopFirstListElementAsText(pollingQueueListKey, value => { if (!string.IsNullOrEmpty(value)) { entityIds.Add(value); } }); } pipeline.Flush(); } ICollection <ITaskRuntimeInfo> result = this.GetAll(entityIds); Trace.WriteLine("EXIT: {0} polling queue '{1}' tasks reserved for execution.".FormatInvariant(result.Count, pollingQueueKey)); return(result); }
private List <ITaskRuntimeInfo> GetAll(IEnumerable <string> entityIds) { List <ITaskRuntimeInfo> result = new List <ITaskRuntimeInfo>(); using (IRedisPipeline pipeline = this.provider.CreatePipeline()) { foreach (string entityId in entityIds) { string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(entityId); pipeline.GetHash(entityKey, values => { if (values.Count > 0) { result.Add(RedisTaskRuntimeInfoRepository.Convert(values)); } }); } pipeline.Flush(); } return(result); }
/// <inheritdoc /> public void Start(Guid taskId, Guid taskProcessorId, DateTime timestampUtc) { Trace.WriteLine("ENTER: Recording task '{0}' started by processor '{1}' ...".FormatInvariant(taskId, taskProcessorId)); string entityKey = RedisTaskRuntimeInfoRepository.GetEntityKey(taskId); Dictionary <string, string> values = new Dictionary <string, string>() { { "Status", RedisConverter.ToString(TaskStatus.InProgress) }, { "TaskProcessorId", RedisConverter.ToString(taskProcessorId) }, { "StartedUtc", RedisConverter.ToString(timestampUtc) } }; using (IRedisTransaction transaction = this.Provider.CreateTransaction()) { transaction.SetHashValues(entityKey, values); transaction.RemoveFromList(RedisTaskRuntimeInfoRepository.PendingTasksList, RedisConverter.ToString(taskId)); transaction.AddToList(RedisTaskRuntimeInfoRepository.ActiveTasksList, RedisConverter.ToString(taskId)); transaction.Commit(); } Trace.WriteLine("EXIT: Task '{0}' assigned to processor '{1}' recorded.".FormatInvariant(taskId, taskProcessorId)); }
private static string GetEntityKey(Guid entityId) { return(RedisTaskRuntimeInfoRepository.GetEntityKey(RedisConverter.ToString(entityId))); }