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."); }
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); }
protected abstract Task CreateCoWorkerAndExecuteAsync(IWorkerReceiver broadcaster, WorkerConnectionGroupContext workerConnection, string workerName, CancellationToken cancellationToken, TaskFailSignal failSignal);
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); }