示例#1
0
        public async Task RunAsync(
            string workerName,
            int processCount,
            int maxWorkerPerProcess,                                 // TODO: remove it
            int executePerWorker,                                    // TODO: remove it
            ConsoleAppFramework.ConsoleAppContext consoleAppContext) // TODO:remove this context.
        {
            var cancellationToken = consoleAppContext.CancellationToken;
            var args = consoleAppContext.Arguments;

            ThreadPoolUtility.SetMinThread(maxWorkerPerProcess);
            // validate worker is exists.
            if (!workers.TryGetWorker(workerName, out var workerInfo))
            {
                throw new InvalidOperationException($"Worker:{workerName} does not found in assembly.");
            }

            var failSignal = new TaskFailSignal();

            using (masterHost = StartMasterHost(args, cancellationToken))
                await using (options.ScalingProvider)
                {
                    var workerConnection = masterHost.Services.GetRequiredService <WorkerConnectionGroupContext>();
                    workerConnection.Initialize(processCount, options.WorkerDisconnectedBehaviour == WorkerDisconnectedBehaviour.Stop);

                    logger.LogInformation("Starting worker nodes.");
                    await options.ScalingProvider.StartWorkerAsync(options, processCount, provider, failSignal, cancellationToken).WithTimeoutAndCancellationAndTaskSignal(options.Timeout, cancellationToken, failSignal.Task);

                    // wait worker is connected
                    await workerConnection.WaitAllConnectedWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);

                    var broadcaster = workerConnection.Broadcaster;

                    Master?master = default;
                    if (workerInfo.MasterType != null)
                    {
                        master = provider.GetRequiredService(workerInfo.MasterType) as Master;
                    }

                    // MasterSetup
                    if (master != null)
                    {
                        logger.LogTrace("Invoke MasterSetup");
                        using (var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                        {
                            linkedToken.CancelAfter(options.Timeout);
                            await master.SetupAsync(linkedToken.Token);
                        }
                    }

                    await CreateCoWorkerAndExecuteAsync(broadcaster, workerConnection, workerName, cancellationToken, failSignal);

                    // Worker Teardown
                    logger.LogTrace("Send SetTeardownup command to workers and wait complete message.");
                    broadcaster.Teardown();
                    await workerConnection.OnTeardown.WaitWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);

                    options.OnExecuteResult?.Invoke(workerConnection.ExecuteResult.ToArray(), options, new ExecuteScenario(workerName, processCount, maxWorkerPerProcess, executePerWorker));

                    // Worker Shutdown
                    broadcaster.Shutdown();

                    // MasterTeardown
                    if (master != null)
                    {
                        logger.LogTrace("Invoke MasterTeardown");
                        using (var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                        {
                            linkedToken.CancelAfter(options.Timeout);
                            await master.TeardownAsync(linkedToken.Token);
                        }
                    }

                    await Task.Delay(TimeSpan.FromSeconds(1)); // wait Shutdown complete?
                }

            logger.LogInformation("Master shutdown.");
        }
示例#2
0
        protected override async Task CreateCoWorkerAndExecuteAsync(IWorkerReceiver broadcaster, WorkerConnectionGroupContext workerConnection, string workerName, CancellationToken cancellationToken, TaskFailSignal failSignal)
        {
            var loopCount = maxWorkerPerProcess / workerSpawnCount;

            for (int i = 0; i < loopCount; i++)
            {
                // Worker CreateCoWorker
                logger.LogTrace("Send CreateWorker/Setup command to workers and wait complete message.");
                workerConnection.OnCreateCoWorkerAndSetup.Reset();
                broadcaster.CreateCoWorkerAndSetup(workerSpawnCount, workerName);
                await workerConnection.OnCreateCoWorkerAndSetup.WaitWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);

                // Worker Execute
                if (i == 0)
                {
                    logger.LogTrace("Send Execute command to workers.");
                    broadcaster.ExecuteUntilReceiveStop();
                }

                // Wait Spawn.
                await Task.Delay(TimeSpan.FromSeconds(workerSpawnSecond));
            }

            // Send Stop Command
            logger.LogTrace("Send Stop command to workers.");
            broadcaster.Stop();

            // Wait Execute Complete.
            await workerConnection.OnExecute.WaitWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);
        }
示例#3
0
 protected abstract Task CreateCoWorkerAndExecuteAsync(IWorkerReceiver broadcaster, WorkerConnectionGroupContext workerConnection, string workerName, CancellationToken cancellationToken, TaskFailSignal failSignal);
示例#4
0
        protected override async Task CreateCoWorkerAndExecuteAsync(IWorkerReceiver broadcaster, WorkerConnectionGroupContext workerConnection, string workerName, CancellationToken cancellationToken, TaskFailSignal failSignal)
        {
            // Worker CreateCoWorker
            logger.LogTrace("Send CreateWorker/Setup command to workers and wait complete message.");
            broadcaster.CreateCoWorkerAndSetup(workerPerProcess, workerName);
            await workerConnection.OnCreateCoWorkerAndSetup.WaitWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);

            // Worker Execute
            logger.LogTrace("Send Execute command to workers and wait complete message.");
            broadcaster.Execute(executePerWorker);
            await workerConnection.OnExecute.WaitWithTimeoutAsync(options.Timeout, cancellationToken, failSignal.Task);
        }