예제 #1
0
        public Task AbandonTaskOrchestrationWorkItemAsync(TaskOrchestrationWorkItem workItem)
        {
            if (OrchestrationsServiceScopes.TryRemove(workItem.InstanceId, out var serviceScope))
            {
                serviceScope.Dispose();
            }

            return(_innerOrchestrationService.AbandonTaskOrchestrationWorkItemAsync(workItem));
        }
예제 #2
0
        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
            }
        }