internal void SendOutbox()

in src/WebJobs.Extensions.DurableTask/ContextImplementations/DurableEntityContext.cs [647:720]


        internal void SendOutbox(OrchestrationContext innerContext, bool writeBackSuccessful, ResponseMessage serializationErrorMessage)
        {
            lock (this.outbox)
            {
                foreach (var message in this.outbox)
                {
                    if (message is LockMessage lockMessage)
                    {
                        this.Config.TraceHelper.SendingEntityMessage(
                            this.InstanceId,
                            this.ExecutionId,
                            lockMessage.Target.InstanceId,
                            lockMessage.EventName,
                            lockMessage.EventContent);

                        innerContext.SendEvent(lockMessage.Target, lockMessage.EventName, lockMessage.EventContent);
                    }
                    else if (message is ResultMessage resultMessage)
                    {
                        // Since for all of the operations in the batch, their effect on the entity state
                        // is lost, we don't want the calling orchestrations to think everything is o.k.
                        // They should be notified, so we replace all non-error operation results
                        // with an exception result.
                        if (!writeBackSuccessful && !resultMessage.IsError)
                        {
                            resultMessage.EventContent = serializationErrorMessage;
                        }

                        this.Config.TraceHelper.SendingEntityMessage(
                            this.InstanceId,
                            this.ExecutionId,
                            resultMessage.Target.InstanceId,
                            resultMessage.EventName,
                            resultMessage.EventContent);

                        innerContext.SendEvent(resultMessage.Target, resultMessage.EventName, resultMessage.EventContent);
                    }
                    else if (!writeBackSuccessful)
                    {
                        // all other messages (signals and fire-and-forget) are suppressed if the writeback failed
                        // this helps to keep the observer pattern correct, for example.
                    }
                    else if (message is OperationMessage operationMessage)
                    {
                        if (!operationMessage.EventContent.ScheduledTime.HasValue)
                        {
                            this.State.MessageSorter.LabelOutgoingMessage(operationMessage.EventContent, operationMessage.Target.InstanceId, DateTime.UtcNow, this.Config.MessageReorderWindow);
                        }

                        this.Config.TraceHelper.SendingEntityMessage(
                            this.InstanceId,
                            this.ExecutionId,
                            operationMessage.Target.InstanceId,
                            operationMessage.EventName,
                            operationMessage.EventContent);

                        innerContext.SendEvent(operationMessage.Target, operationMessage.EventName, operationMessage.EventContent);
                    }
                    else if (message is FireAndForgetMessage fireAndForgetMessage)
                    {
                        var dummyTask = innerContext.CreateSubOrchestrationInstance<object>(
                          fireAndForgetMessage.FunctionName,
                          this.Config.Options.DefaultVersion,
                          fireAndForgetMessage.InstanceId,
                          fireAndForgetMessage.Input,
                          new Dictionary<string, string>() { { OrchestrationTags.FireAndForget, "" } });

                        System.Diagnostics.Debug.Assert(dummyTask.IsCompleted, "task should be fire-and-forget");
                    }
                }

                this.outbox.Clear();
            }
        }