예제 #1
0
        public override async Task Run(Func <bool> shutdown)
        {
            string closeReason = "Module shutdown";

            try {
                var taskRun = SendVoidRequest(new RunMsg());

                while (!shutdown() && !taskRun.IsCompleted && !taskReceive.IsCompleted)
                {
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }

                if (taskRun.IsCompleted)
                {
                    closeReason = $"External module {moduleName} returned from Run unexpectedly.";
                    logger.Warn(closeReason);
                }
                else if (taskReceive.IsFaulted || process.HasExited)
                {
                    Thread.Sleep(500); // no need for async wait here
                    closeReason = $"External module {moduleName} terminated unexpectedly.";
                    throw new Exception(closeReason);
                }
                else
                {
                    var taskShutdown = SendVoidRequest(new ShutdownMsg());

                    Timestamp tStart  = Timestamp.Now;
                    const int timeout = 20;

                    while (!taskRun.IsCompleted)
                    {
                        if (taskShutdown.IsFaulted || process.HasExited)
                        {
                            logger.Warn("External module terminated unexpectedly during shutdown.");
                            break;
                        }

                        if (Timestamp.Now - tStart > Duration.FromSeconds(timeout))
                        {
                            logger.Warn($"Module did not return from Run within {timeout} seconds. Killing process...");
                            break;
                        }

                        await Task.WhenAny(taskRun, Task.Delay(2000));

                        if (!taskRun.IsCompleted)
                        {
                            long secondsUntilTimeout = (tStart.AddSeconds(timeout) - Timestamp.Now).TotalMilliseconds / 1000;
                            logger.Info("Waiting for Run completion (timeout in {0} seconds)...", secondsUntilTimeout);
                        }
                    }
                }
            }
            finally {
                connection.Close(closeReason);
                StopProcess(process);
                process = null;
            }
        }
예제 #2
0
        public async override Task InitAbort()
        {
            if (process == null)
            {
                return;                  // abort already happened in Init()
            }
            var taskAbort = SendVoidRequest(new InitAbortMsg());

            try {
                Timestamp tStart  = Timestamp.Now;
                const int timeout = 12;

                while (!taskAbort.IsCompleted)
                {
                    if (process.HasExited)
                    {
                        logger.Warn("External module terminated unexpectedly during init abort.");
                        break;
                    }

                    if (Timestamp.Now - tStart > Duration.FromSeconds(timeout))
                    {
                        logger.Warn($"Module did not return from InitAbort within {timeout} seconds. Killing process...");
                        break;
                    }

                    await Task.WhenAny(taskAbort, Task.Delay(2000));

                    if (!taskAbort.IsCompleted)
                    {
                        long secondsUntilTimeout = (tStart.AddSeconds(timeout) - Timestamp.Now).TotalMilliseconds / 1000;
                        logger.Info("Waiting for InitAbort completion (timeout in {0} seconds)...", secondsUntilTimeout);
                    }
                }
            }
            finally {
                connection.Close("Init abort");
                StopProcess(process);
                process = null;
            }
        }