public override async Task LockNextTaskOrchestrationWorkItem(IAsyncStreamReader <TaskOrchestrationRequest> requestStream, IServerStreamWriter <TaskOrchestrationResponse> responseStream, ServerCallContext context) { try { TaskOrchestrationWorkItem workItem = null; // Receive and reply each message await foreach (var message in requestStream.ReadAllAsync(context.CancellationToken)) { switch (message.MessageCase) { case TaskOrchestrationRequest.MessageOneofCase.LockRequest: var lockRequest = message.LockRequest; var orchestrations = lockRequest.Orchestrations.Select(x => new NameVersion(x.Name, x.Version)).ToArray(); workItem = await(lockRequest.AllOrchestrations ? _orchestrationService .LockNextTaskOrchestrationWorkItemAsync(lockRequest.ReceiveTimeout.ToTimeSpan(), context.CancellationToken) : (_extendedOrchestrationService ?? throw DistributedWorkersNotSupported()) .LockNextTaskOrchestrationWorkItemAsync(lockRequest.ReceiveTimeout.ToTimeSpan(), orchestrations, context.CancellationToken) ); var lockResponse = new TaskOrchestrationResponse { LockResponse = new LockNextTaskOrchestrationWorkItemResponse { WorkItem = workItem == null ? null : new DurableTaskGrpc.TaskOrchestrationWorkItem { InstanceId = workItem.InstanceId, LockedUntilUtc = Timestamp.FromDateTime(workItem.LockedUntilUtc), Events = { workItem.OrchestrationRuntimeState.Events.Select(_options.DataConverter.Serialize) }, NewMessages = { workItem.NewMessages.Select(_options.DataConverter.Serialize) } } } }; context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(lockResponse); break; case TaskOrchestrationRequest.MessageOneofCase.RenewRequest: var renewRequest = message.RenewRequest; await _orchestrationService.RenewTaskOrchestrationWorkItemLockAsync(workItem); var renewResponse = new TaskOrchestrationResponse { RenewResponse = new RenewTaskOrchestrationWorkItemLockResponse { LockedUntilUtc = Timestamp.FromDateTime(workItem.LockedUntilUtc) } }; context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(renewResponse); break; case TaskOrchestrationRequest.MessageOneofCase.CompleteRequest: var completeRequest = message.CompleteRequest; var outboundMessages = completeRequest.OutboundMessages.Select(x => _options.DataConverter.Deserialize <TaskMessage>(x)).ToArray(); var timerMessages = completeRequest.TimerMessages.Select(x => _options.DataConverter.Deserialize <TaskMessage>(x)).ToArray(); var orchestratorMessages = completeRequest.OrchestratorMessages.Select(x => _options.DataConverter.Deserialize <TaskMessage>(x)).ToArray(); var continuedAsNewMessage = string.IsNullOrEmpty(completeRequest.ContinuedAsNewMessage) ? null : _options.DataConverter.Deserialize <TaskMessage>(completeRequest.ContinuedAsNewMessage); var newEvents = completeRequest.NewEvents.Select(x => _options.DataConverter.Deserialize <HistoryEvent>(x)).ToArray(); workItem.OrchestrationRuntimeState ??= new OrchestrationRuntimeState(); foreach (var newEvent in newEvents) { workItem.OrchestrationRuntimeState.AddEvent(newEvent); } workItem.OrchestrationRuntimeState.Status = completeRequest.NewStatus; var newOrchestrationRuntimeState = workItem.OrchestrationRuntimeState; var newOrchestrationRuntimeStateEvents = completeRequest.NewOrchestrationEvents.Select(x => _options.DataConverter.Deserialize <HistoryEvent>(x)).ToArray(); if (newOrchestrationRuntimeStateEvents.Length > 0) { newOrchestrationRuntimeState = new OrchestrationRuntimeState(); foreach (var newEvent in newOrchestrationRuntimeStateEvents) { newOrchestrationRuntimeState.AddEvent(newEvent); } newOrchestrationRuntimeState.Status = completeRequest.NewOrchestrationStatus; } var orchestrationState = Utils.BuildOrchestrationState(newOrchestrationRuntimeState); await _orchestrationService.CompleteTaskOrchestrationWorkItemAsync( workItem, newOrchestrationRuntimeState, outboundMessages, orchestratorMessages, timerMessages, continuedAsNewMessage, orchestrationState); newOrchestrationRuntimeState.NewEvents.Clear(); workItem.OrchestrationRuntimeState = newOrchestrationRuntimeState; context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(new TaskOrchestrationResponse { CompleteResponse = new CompleteTaskOrchestrationWorkItemResponse() }); break; case TaskOrchestrationRequest.MessageOneofCase.FetchRequest: var fetchRequest = message.FetchRequest; if (workItem.Session == null) { var fetchResponse = new TaskOrchestrationResponse { FetchResponse = new FetchNewOrchestrationMessagesResponse { NewMessages = null } }; context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(fetchResponse); } else { var newMessages = await workItem.Session.FetchNewOrchestrationMessagesAsync(workItem); var fetchResponse = new TaskOrchestrationResponse { FetchResponse = new FetchNewOrchestrationMessagesResponse { NewMessages = newMessages == null ? null : new OrchestrationMessages { Messages = { newMessages.Select(_options.DataConverter.Serialize) } } } }; context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(fetchResponse); } break; case TaskOrchestrationRequest.MessageOneofCase.ReleaseRequest: var releaseRequest = message.ReleaseRequest; await _orchestrationService.ReleaseTaskOrchestrationWorkItemAsync(workItem); context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(new TaskOrchestrationResponse { ReleaseResponse = new ReleaseTaskOrchestrationWorkItemResponse() }); break; case TaskOrchestrationRequest.MessageOneofCase.AbandonRequest: var abandonRequest = message.AbandonRequest; await _orchestrationService.AbandonTaskOrchestrationWorkItemAsync(workItem); context.CancellationToken.ThrowIfCancellationRequested(); await responseStream.WriteAsync(new TaskOrchestrationResponse { AbandonResponse = new AbandonTaskOrchestrationWorkItemLockResponse() }); break; } } } catch (OperationCanceledException) when(context.CancellationToken.IsCancellationRequested) { // Avoid exceptions when clients cancel request } }
public Task CompleteTaskOrchestrationWorkItemAsync(TaskOrchestrationWorkItem workItem, OrchestrationRuntimeState newOrchestrationRuntimeState, IList <TaskMessage> outboundMessages, IList <TaskMessage> orchestratorMessages, IList <TaskMessage> timerMessages, TaskMessage continuedAsNewMessage, OrchestrationState orchestrationState) { return(_innerOrchestrationService.CompleteTaskOrchestrationWorkItemAsync(workItem, newOrchestrationRuntimeState, outboundMessages, orchestratorMessages, timerMessages, continuedAsNewMessage, orchestrationState)); }