// Start and Stop commands are composite commands that take multiple turns.
        // Ee don't wnat them to interleave with other concurrent Start/Stop commands, as well as not with QueueDistributionChangeNotification.
        // Therefore, we serialize them all via the same nonReentrancyGuarantor.
        private Task QueueCommandForExecution(PersistentStreamProviderCommand command, int commandSeqNumber)
        {
            return(nonReentrancyGuarantor.AddNext(() =>
            {
                // skip execution of an older/previous command since already got a newer command.
                if (commandSeqNumber < latestCommandNumber)
                {
                    Log(ErrorCode.PersistentStreamPullingManager_15,
                        "Skipping execution of command number {0} since already received a later command (already have command number {1}).",
                        commandSeqNumber, latestCommandNumber);
                    return Task.CompletedTask;
                }
                switch (command)
                {
                case PersistentStreamProviderCommand.StartAgents:
                    return StartAgents();

                case PersistentStreamProviderCommand.StopAgents:
                    return StopAgents();

                default:
                    throw new OrleansException(String.Format("PullingAgentManager got unsupported command {0}", command));
                }
            }));
        }
        public async Task <object> ExecuteCommand(PersistentStreamProviderCommand command, object arg)
        {
            latestCommandNumber++;
            int commandSeqNumber = latestCommandNumber;

            try
            {
                Log(ErrorCode.PersistentStreamPullingManager_13,
                    String.Format("Got command {0}{1}: commandSeqNumber = {2}, managerState = {3}.",
                                  command, arg != null ? " with arg " + arg : String.Empty, commandSeqNumber, managerState));

                switch (command)
                {
                case PersistentStreamProviderCommand.StartAgents:
                case PersistentStreamProviderCommand.StopAgents:
                    await QueueCommandForExecution(command, commandSeqNumber);

                    return(null);

                case PersistentStreamProviderCommand.GetAgentsState:
                    return(managerState);

                case PersistentStreamProviderCommand.GetNumberRunningAgents:
                    return(NumberRunningAgents);

                default:
                    throw new OrleansException(String.Format("PullingAgentManager does not support command {0}.", command));
                }
            }
            finally
            {
                Log(ErrorCode.PersistentStreamPullingManager_15,
                    String.Format("Done executing command {0}: commandSeqNumber = {1}, managerState = {2}, num running agents = {3}.",
                                  command, commandSeqNumber, managerState, NumberRunningAgents));
            }
        }
 // Start and Stop commands are composite commands that take multiple turns. 
 // Ee don't wnat them to interleave with other concurrent Start/Stop commands, as well as not with QueueDistributionChangeNotification.
 // Therefore, we serialize them all via the same nonReentrancyGuarantor.
 private Task QueueCommandForExecution(PersistentStreamProviderCommand command, int commandSeqNumber)
 {
     return nonReentrancyGuarantor.AddNext(() =>
     {
         // skip execution of an older/previous command since already got a newer command.
         if (commandSeqNumber < latestCommandNumber)
         {
             Log(ErrorCode.PersistentStreamPullingManager_15,
                 "Skipping execution of command number {0} since already received a later command (already have command number {1}).",
                 commandSeqNumber, latestCommandNumber);
             return TaskDone.Done;
         }
         switch (command)
         {
             case PersistentStreamProviderCommand.StartAgents:
                 return StartAgents();
             case PersistentStreamProviderCommand.StopAgents:
                 return StopAgents();
             default:
                 throw new OrleansException(String.Format("PullingAgentManager got unsupported command {0}", command));
         }
     });
 }
        public async Task<object> ExecuteCommand(PersistentStreamProviderCommand command, object arg)
        {
            latestCommandNumber++;
            int commandSeqNumber = latestCommandNumber;

            try
            {
                Log(ErrorCode.PersistentStreamPullingManager_13,
                    String.Format("Got command {0}{1}: commandSeqNumber = {2}, managerState = {3}.",
                    command, arg != null ? " with arg " + arg : String.Empty, commandSeqNumber, managerState));

                switch (command)
                {
                    case PersistentStreamProviderCommand.StartAgents:
                    case PersistentStreamProviderCommand.StopAgents:
                        await QueueCommandForExecution(command, commandSeqNumber);
                        return null;
                    case PersistentStreamProviderCommand.GetAgentsState:
                        return managerState;
                    case PersistentStreamProviderCommand.GetNumberRunningAgents:
                        return NumberRunningAgents;
                    default:
                        throw new OrleansException(String.Format("PullingAgentManager does not support command {0}.", command));
                }
            }
            finally
            {
                Log(ErrorCode.PersistentStreamPullingManager_15,
                    String.Format("Done executing command {0}: commandSeqNumber = {1}, managerState = {2}, num running agents = {3}.", 
                    command, commandSeqNumber, managerState, NumberRunningAgents));
            }
        }