public void ForkOrchestration <TReturn2>(IOrchestration <TReturn2> orchestration) { if (!RecordOrReplayCall(MessageType.ForkOperation, out var opid, out var clock, out var instanceId)) { if (!process.Orchestrations.TryGetValue(orchestration.GetType(), out var orchestrationInfo)) { throw new BuilderException($"undefined orchestration type {orchestration.GetType().FullName}."); } orchestrationInfo.CanExecuteLocally(orchestration, out var destination); (ForkedDestinations ?? (ForkedDestinations = new SortedSet <uint>())).Add(destination); var message = orchestrationInfo.CreateForkMessage(orchestration); message.Opid = opid; message.Clock = clock; message.Parent = this.Opid; message.LockedByCaller = false; process.Send(destination, message); process.Telemetry?.OnApplicationEvent( processId: process.ProcessId, id: opid.ToString(), name: orchestration.ToString(), parent: Opid.ToString(), opSide: OperationSide.Fork, opType: OperationType.Orchestration, duration: 0 ); } }
public Task <TReturn2> PerformOrchestration <TReturn2>(IOrchestration <TReturn2> orchestration) { if (!RecordOrReplayCall(MessageType.RequestOperation, out var opid, out var clock, out var instanceId)) { if (!process.Orchestrations.TryGetValue(orchestration.GetType(), out var orchestrationInfo)) { throw new BuilderException($"undefined orchestration type {orchestration.GetType().FullName}."); } if (LockSet != null) { if (!orchestrationInfo.RequiresLocks(orchestration, out var locks)) { throw new SynchronizationDisciplineException("an orchestration called from a locked context must be locked also"); } foreach (var l in locks) { if (!LockSet.Contains(l)) { throw new SynchronizationDisciplineException("to perform an orchestration in a locked context, the caller's affinities must contain the callee's affinities"); } } } orchestrationInfo.CanExecuteLocally(orchestration, out uint destination); var message = orchestrationInfo.CreateRequestMessage(orchestration); message.Opid = opid; message.Clock = clock; message.Parent = this.Opid; message.LockedByCaller = (LockSet != null); process.Send(destination, message); } if (!ReplayReturn(MessageType.RespondToOperation, opid, out var result)) { var continuationInfo = new ContinuationInfo <TReturn2>(orchestration.ToString(), OperationType.Orchestration); Continuations[opid] = continuationInfo; return(continuationInfo.Tcs.Task); } else { if (process.Serializer.DeserializeException(result, out var e)) { return(Task.FromException <TReturn2>(e)); } else { return(Task.FromResult((TReturn2)result)); } } }
internal override void Apply(Process process) { var opInfo = process.Orchestrations[Orchestration.GetType()]; var opid = process.NextOpid; opInfo.CanExecuteLocally(Orchestration, out var dest); var msg = opInfo.CreateForkMessage(Orchestration); msg.Opid = opid; msg.Clock = 0; msg.Parent = 0; process.Send(dest, msg); }
void IContextWithForks.ForkOrchestration <TReturn>(IOrchestration <TReturn> orchestration) { if (!process.Orchestrations.TryGetValue(orchestration.GetType(), out var orchestrationInfo)) { throw new BuilderException($"undefined orchestration type {orchestration.GetType().FullName}."); } orchestrationInfo.CanExecuteLocally(orchestration, out uint destination); var opid = process.NextOpid; var message = orchestrationInfo.CreateForkMessage(orchestration); message.Opid = opid; message.Parent = CurrentOpid; process.Send(destination, message); process.Telemetry?.OnApplicationEvent( processId: process.ProcessId, id: opid.ToString(), name: orchestration.ToString(), parent: CurrentOpid.ToString(), opSide: OperationSide.Fork, opType: OperationType.Orchestration, duration: 0 ); }