public MessageSequence <TMessage> Complete <TMessage>() { _logger.LogDebug($"Message Sequence for '{_globalMessageId}' completes with '{typeof(TMessage).Name}'."); var sequenceDef = _repository.GetOrCreate(_globalMessageId); var messageTcs = new TaskCompletionSource <TMessage>(); var sequence = new MessageSequence <TMessage> { Task = messageTcs.Task }; sequenceDef.TaskCompletionSource.Task.ContinueWith(tObj => { UpdateSequenceFinalState(sequence); messageTcs.TrySetResult((TMessage)tObj.Result); }); Func <TMessage, TMessageContext, Task> func = (message, context) => { Task .WhenAll(sequenceDef.State.HandlerTasks) .ContinueWith(t => sequenceDef.TaskCompletionSource.TrySetResult(message)); return(Task.FromResult(true)); }; var bindTask = _chainTopology.BindToExchange <TMessage>(_globalMessageId); _dispatcher.AddMessageHandler(_globalMessageId, func); Task .WhenAll(bindTask) .ContinueWith(t => _publishAsync()) .Unwrap() .Wait(); Timer timeoutTimer = null; timeoutTimer = new Timer(state => { timeoutTimer?.Dispose(); var seq = _repository.Get(_globalMessageId); if (seq != null) { seq.State.Aborted = true; _repository.Update(seq); UpdateSequenceFinalState(sequence); } messageTcs.TrySetException( new TimeoutException( $"Unable to complete sequence {_globalMessageId} in {_mainCfg.RequestTimeout.ToString("g")}. Operation Timed out.")); }, null, _mainCfg.RequestTimeout, new TimeSpan(-1)); return(sequence); }
public void AddMessageHandler <TMessage, TMessageContext>(Guid globalMessageId, Func <TMessage, TMessageContext, Task> func, StepOption configuration) where TMessageContext : IMessageContext { var sequence = _sequenceRepository.GetOrCreate(globalMessageId); sequence.StepDefinitions.Add(new StepDefinition { Handler = (o, context) => func((TMessage)o, (TMessageContext)context), Type = typeof(TMessage), Optional = configuration?.Optional ?? false, AbortsExecution = configuration?.AbortsExecution ?? false }); _sequenceRepository.Update(sequence); }