Beispiel #1
0
        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
                    );
            }
        }
Beispiel #2
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));
         }
     }
 }
Beispiel #3
0
        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
                );
        }