internal override void Enter <TKey>(Process process, TKey localkey, Stopwatch stopwatch, out bool isExiting) { var completed = Execute <TKey>(process, localkey, out var result); if (!completed) { // we did not actually execute, but are waiting for initialization ack isExiting = false; return; // keep lock } if (MessageType != MessageType.ForkUpdate) { process.Send(process.GetOrigin(Opid), new RespondToLocal() { Opid = Opid, Parent = Parent, Result = result }); } else { process.CheckForUnhandledException(result); } process.Telemetry?.OnApplicationEvent( processId: process.ProcessId, id: Opid.ToString(), name: LabelForTelemetry, parent: Parent.ToString(), opSide: OperationSide.Callee, opType: OperationType.Local, duration: stopwatch.Elapsed.TotalMilliseconds ); isExiting = true; }
public async Task Run() { Stopwatch messageProcessingTimer = new Stopwatch(); messageProcessingTimer?.Start(); if (info.RequiresLocks(Request, out var locks)) { LockSet = locks; if (!LockedByCaller) { await AcquireLocks(); } } object result; try { if (Request is IReadOrchestration <TReturn> ro) { result = await ro.Execute(this); } else { result = await((IOrchestration <TReturn>)Request).Execute(this); } if (Continuations.Count > 0) { throw new RuntimeException("Operation completed prematurely. Must await all spawned tasks, or use ForkXXX or ScheduleXXX for detached operations."); } } catch (Exception e) { result = process.Serializer.SerializeException(e); } if (LockSet != null && !LockedByCaller) { ReleaseLocks(); } messageProcessingTimer.Stop(); var elapsed = messageProcessingTimer.Elapsed.TotalMilliseconds; process.Telemetry?.OnApplicationEvent( processId: process.ProcessId, id: Opid.ToString(), name: Request.ToString(), parent: Parent.ToString(), opSide: OperationSide.Callee, opType: OperationType.Orchestration, duration: elapsed ); switch (OrchestrationType) { case OrchestrationType.Perform: var response = new RespondToOrchestration() { Opid = Opid, Result = result, Clock = Clock, Parent = Parent, }; process.Send(process.GetOrigin(Opid), response); break; case OrchestrationType.Fork: process.CheckForUnhandledException(result); if (process.FinishStates.TryGetValue(Parent, out var finishState)) { finishState.RemovePending(Opid); } break; case OrchestrationType.Initialize: process.CheckForUnhandledException(result); var initializationRequest = (IInitializationRequest)Request; initializationRequest.SetStateToFinalResult(process); var initresponse = new AckInitialization() { OriginalOpid = Parent, PartitionKey = initializationRequest.GetPartitionKey(), Opid = Opid, Clock = Clock, Parent = Parent, }; process.Send(process.GetOrigin(Opid), initresponse); break; } }