Example #1
0
        void Terminate(AgentProcessState agentProcessState)
        {
            lock (runningAgentProcessStateLock) {
                agentProcessState.AgentProcess.UnexpectedlyTerminated
                    -= HandleAgentProcessUnexpectedlyTerminated;

                if (runningAgentProcessState == agentProcessState)
                {
                    runningAgentProcessState = null;
                }
            }

            AgentProcessTicket [] copiedTickets;
            lock (tickets) {
                copiedTickets = tickets.ToArray();
                tickets.Clear();
            }

            MainThread.Post(() => {
                foreach (var ticket in copiedTickets)
                {
                    try {
                        ticket.NotifyDisconnected();
                    } catch (Exception e) {
                        Log.Error(TAG, "exception when notifying ticket of disconnect", e);
                    }
                }
            });

            // Always run this as a form of disposal, because new AgentProcesses are created on-demand.
            // AgentProcess implementations should not let their Terminate implementations throw.
            agentProcessState.AgentProcess.TerminateAgentProcessAsync().Forget();
        }
Example #2
0
 async Task MonitorConnectionAsync(AgentProcessState agentProcessState)
 {
     // NOTE: we do not pass the cancellation token for the
     // ticket since the AgentClient may outlive the ticket
     try {
         await agentProcessState
         .AgentClient
         .OpenAgentMessageChannel(default(CancellationToken))
         .ConfigureAwait(false);
     } finally {
         HandleAgentProcessUnexpectedlyTerminated(
             agentProcessState?.AgentProcess, EventArgs.Empty);
     }
 }
Example #3
0
        public async Task <IAgentProcessState> StartAsync(
            AgentProcessTicket ticket,
            CancellationToken cancellationToken)
        {
            if (ticket == null)
            {
                throw new ArgumentNullException(nameof(ticket));
            }

            if (ticket.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(ticket));
            }

            try {
                LogStartStatus(ticket, "waiting for all clear");
                await startWait.WaitAsync().ConfigureAwait(false);

                AgentProcessState agentProcessState;

                lock (runningAgentProcessStateLock) {
                    if (runningAgentProcessState != null)
                    {
                        LogStartStatus(ticket, "using existing agent process manager");
                        RegisterTicket(ticket);
                        return(runningAgentProcessState);
                    }
                }

                LogStartStatus(ticket, "creating new agent process manager");
                agentProcessState = new AgentProcessState(workbookApp, agentProcessType);
                agentProcessState.AgentProcess.UnexpectedlyTerminated
                    += HandleAgentProcessUnexpectedlyTerminated;

                var identifyAgentRequest = ClientApp
                                           .SharedInstance
                                           .WebServer
                                           .AgentIdentificationManager
                                           .GetAgentIdentityRequest(cancellationToken);

                LogStartStatus(ticket, "waiting for agent process manager to start");
                await agentProcessState.AgentProcess.StartAgentProcessAsync(
                    identifyAgentRequest,
                    ticket.MessageService,
                    cancellationToken).ConfigureAwait(false);

                LogStartStatus(ticket, "requesting agent identity");
                agentProcessState.AgentIdentity = await ClientApp
                                                  .SharedInstance
                                                  .WebServer
                                                  .AgentIdentificationManager
                                                  .GetAgentIdentityAsync(identifyAgentRequest).ConfigureAwait(false);

                var agentAssociable = agentProcessState.AgentProcess as IAgentAssociable;
                if (agentAssociable == null)
                {
                    LogStartStatus(ticket, "creating agent client");
                    agentProcessState.AgentClient = new AgentClient(
                        agentProcessState.AgentIdentity.Host,
                        agentProcessState.AgentIdentity.Port);
                }
                else
                {
                    LogStartStatus(ticket, "waiting on agent association");
                    var agentAssociation = await agentAssociable.GetAgentAssociationAsync(
                        agentProcessState.AgentIdentity,
                        cancellationToken).ConfigureAwait(false);

                    agentProcessState.AgentIdentity = agentAssociation.Identity;
                    agentProcessState.AgentClient   = agentAssociation.Client;
                }

                try {
                    LogStartStatus(ticket, "registering ticket");
                    RegisterTicket(ticket);
                } catch (ObjectDisposedException e) {
                    Terminate(agentProcessState);
                    throw e;
                }

                lock (runningAgentProcessStateLock)
                    runningAgentProcessState = agentProcessState;

                MonitorConnectionAsync(agentProcessState).Forget();

                return(agentProcessState);
            } catch (Exception e) {
                Log.Error(TAG, nameof(StartAsync), e);
                throw e;
            } finally {
                startWait.Release();
            }
        }