static async Task <IEnumerable <IPhysicalDrive> > GetPhysicalDrives(Arguments arguments) { if (arguments.Fake) { var drives = new List <FakePhysicalDrive>(); if (!string.IsNullOrWhiteSpace(arguments.SourcePath)) { drives.Add(new FakePhysicalDrive(arguments.SourcePath, "Fake", "Fake", arguments.Size ?? 1024 * 1024)); } if (!string.IsNullOrWhiteSpace(arguments.DestinationPath)) { drives.Add(new FakePhysicalDrive(arguments.DestinationPath, "Fake", "Fake", arguments.Size ?? 1024 * 1024)); } return(drives); } var physicalDriveManager = new PhysicalDriveManagerFactory(new NullLoggerFactory()).Create(); return((await physicalDriveManager.GetPhysicalDrives()).ToList()); }
public static async Task Start(string baseUrl, int processId) { var hasDebugEnabled = ApplicationDataHelper.HasDebugEnabled(Constants.AppName); #if RELEASE SetupReleaseLogging(hasDebugEnabled); #else SetupDebugLogging(); #endif var serviceCollection = new ServiceCollection(); ConfigureServices(serviceCollection); var serviceProvider = serviceCollection.BuildServiceProvider(); var loggerFactory = serviceProvider.GetService <ILoggerFactory>(); var logger = serviceProvider.GetService <ILogger <Program> >(); if (processId > 0) { KillOtherWorkers(logger, processId); } logger.LogDebug($"Connecting to base url '{baseUrl}'"); var progressHubConnection = new HubConnectionBuilder() .WithUrl($"{baseUrl}/hubs/progress") .WithAutomaticReconnect() .ConfigureLogging(logging => { if (!hasDebugEnabled) { return; } logging.AddSerilog(); }) .Build(); var errorHubConnection = new HubConnectionBuilder() .WithUrl($"{baseUrl}/hubs/error") .WithAutomaticReconnect() .ConfigureLogging(logging => { if (!hasDebugEnabled) { return; } logging.AddSerilog(); }) .Build(); var workerHubConnection = new HubConnectionBuilder() .WithUrl($"{baseUrl}/hubs/worker") .WithAutomaticReconnect() .ConfigureLogging(logging => { if (!hasDebugEnabled) { return; } logging.AddSerilog(); }) .Build(); var resultHubConnection = new HubConnectionBuilder() .WithUrl($"{baseUrl}/hubs/result") .WithAutomaticReconnect() .ConfigureLogging(logging => { if (!hasDebugEnabled) { return; } logging.AddSerilog(); }) .Build(); await progressHubConnection.StartAsync(); await errorHubConnection.StartAsync(); await workerHubConnection.StartAsync(); await resultHubConnection.StartAsync(); logger.LogDebug($"ProgressHubConnection = {progressHubConnection.State}"); logger.LogDebug($"ErrorHubConnection = {errorHubConnection.State}"); logger.LogDebug($"WorkerHubConnection = {workerHubConnection.State}"); logger.LogDebug($"ResultHubConnection = {resultHubConnection.State}"); var physicalDriveManagerFactory = new PhysicalDriveManagerFactory(loggerFactory); var backgroundTaskQueue = new BackgroundTaskQueue(100); var activeBackgroundTaskList = new ActiveBackgroundTaskList(); var queuedHostedService = new QueuedHostedService(backgroundTaskQueue, activeBackgroundTaskList, loggerFactory.CreateLogger <QueuedHostedService>()); var backgroundTaskHandler = new BackgroundTaskHandler( loggerFactory.CreateLogger <BackgroundTaskHandler>(), loggerFactory, progressHubConnection, errorHubConnection, resultHubConnection, physicalDriveManagerFactory.Create(), activeBackgroundTaskList, backgroundTaskQueue); await queuedHostedService.StartAsync(CancellationToken.None); workerHubConnection.On <BackgroundTask>(Constants.HubMethodNames.RunBackgroundTask, async(task) => { logger.LogDebug($"Start handle background task type '{task.Type}' with payload '{task.Payload}'"); try { await backgroundTaskHandler.Handle(task); logger.LogDebug($"End handle background task type '{task.Type}' with payload '{task.Payload}'"); } catch (Exception e) { logger.LogError(e, $"Failed to handle background task '{task.Type}' with payload '{task.Payload}'"); } }); workerHubConnection.On(Constants.HubMethodNames.CancelBackgroundTask, () => { logger.LogDebug("Cancel background task"); try { activeBackgroundTaskList.CancelAll(); } catch (Exception e) { logger.LogError(e, "Failed to cancel background task"); } }); var workerProcessId = Process.GetCurrentProcess().Id; logger.LogDebug($"Worker process id '{workerProcessId}'"); await workerHubConnection.WorkerProcess(workerProcessId); logger.LogDebug("Worker is ready"); var pingFailed = 0; var maxPingFailed = 3; while (true) { await Task.Delay(5000); try { await workerHubConnection.WorkerPing(); pingFailed = 0; } catch (Exception) { pingFailed++; } if (pingFailed <= maxPingFailed) { continue; } logger.LogInformation($"Stopping worker after ping failed {maxPingFailed} times"); return; } }