/// <inheritdoc /> public ITaskImplementation LocateAndCreate(TaskDescription taskDescription) { if (_registeredTaskTypes.TryGetValue(taskDescription.TaskType, out var taskImplementationType)) { return((ITaskImplementation)JsonConvert.DeserializeObject(taskDescription.TaskPayload, taskImplementationType)); } return(null); }
public static TaskDescription ToTaskDescription(ITaskImplementation taskImplementation) { if (taskImplementation == null) { throw new ArgumentNullException(nameof(taskImplementation)); } var description = new TaskDescription(Guid.NewGuid(), taskImplementation.GetType().FullName, JsonConvert.SerializeObject(taskImplementation)); return(description); }
/// <inheritdoc /> protected override async Task RunAsync(CancellationToken cancellationToken) { var queue = await TimeoutRetryHelper.Execute( (token, state) => StateManager.GetOrAddAsync <IReliableQueue <MessageWrapper> >(_queueName), cancellationToken : cancellationToken) .ConfigureAwait(false); while (true) { try { cancellationToken.ThrowIfCancellationRequested(); //peek task description var taskDescriptionMessage = await TimeoutRetryHelper .ExecuteInTransaction(StateManager, (tran, token, state) => queue.TryPeekAsync(tran, TimeSpan.FromSeconds(4), token), cancellationToken : cancellationToken) .ConfigureAwait(false); if (!taskDescriptionMessage.HasValue) { continue; } //deserialize task description, create task implementation var description = this.Deserialize <TaskDescription>(taskDescriptionMessage.Value); var implementation = TaskDescription.ToTaskImplementation(_typeLocator, description); if (implementation == null) { ServiceEventSourceMessageCallback? .Invoke($"Received TaskDescription message with type {description.TaskType} and id {description.TaskId} that could not be transformed into a TaskImplementation type."); continue; } //run task ServiceEventSourceMessageCallback? .Invoke($"Processing TaskDescription message with type {description.TaskType} and id {description.TaskId}, using implementation {implementation.GetType().Name}."); await implementation.ExecuteAsync().ConfigureAwait(false); var taskDescriptionMessageDequeued = await TimeoutRetryHelper .ExecuteInTransaction(StateManager, (tran, token, state) => queue.TryDequeueAsync(tran, TimeSpan.FromSeconds(4), token), cancellationToken : cancellationToken) .ConfigureAwait(false); //dequeue task, compare it with the peeked task if (taskDescriptionMessageDequeued.HasValue && taskDescriptionMessageDequeued.Value.Payload.GetHashCode() == taskDescriptionMessage.Value.Payload.GetHashCode()) { ServiceEventSourceMessageCallback? .Invoke($"Processed TaskDescription message with type {description.TaskType} and id {description.TaskId}, using implementation {implementation.GetType().Name}."); } else { ServiceEventSourceMessageCallback? .Invoke($"Unexpected error. The peeked message is not the dequeued message."); } } catch (TaskCanceledException) {//swallow and move on.. } catch (OperationCanceledException) {//swallow and move on.. } catch (ObjectDisposedException) {//swallow and move on.. } catch (Exception ex) { ServiceEventSourceMessageCallback?.Invoke($"Exception caught while processing messages:'{ex.Message}'"); //swallow and move on.. } finally { await Task.Delay(Period, cancellationToken).ConfigureAwait(false); } } }
public static ITaskImplementation ToTaskImplementation(ITypeLocator typeLocator, TaskDescription taskDescription) { return(typeLocator.LocateAndCreate(taskDescription)); }