public async Task LogExecutionStarting(IProcessor processor) { var logEntry = new DataProcessingServiceLog( $"Starting execution of processor '{processor.DisplayName}'", new ExecutionStartLogEntryDetails( DataProcessingServiceExecutorType.Processor, processor.DisplayName, processor.InputTypes.Count == 1 ? processor.InputTypes.First() : "Multiple", (processor as ISingleOutputProcessor)?.OutputTypeName ?? "Multiple")); await dataProcessingServiceLogger.Log(logEntry); }
private async Task Run(CancellationToken cancellationToken) { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog($"{nameof(PostponedProcessingRunner)} started", null)); await LoadPostponedObjects(); while (!cancellationToken.IsCancellationRequested) { try { var noMoreAttemptsObjects = postponedObjects.Values.Where(x => x.RemainingAttempts <= 0).ToList(); foreach (var noMoreAttemptsObject in noMoreAttemptsObjects) { await RemovePostponedObject(noMoreAttemptsObject.Id); } var readyObjects = postponedObjects.Values.Where(x => !x.MissingData.Any()).ToList(); foreach (var readyObject in readyObjects) { var processingStatus = await RunPostponedObject(readyObject); if (processingStatus != ProcessingStatus.Postponed) { await RemovePostponedObject(readyObject.Id); } } var now = DateTime.UtcNow; var expiredObjects = postponedObjects.Values.Where(x => now > x.LastAttempt + x.MaxWaitTime).ToList(); foreach (var expiredObject in expiredObjects) { var processingStatus = await RunPostponedObject(expiredObject); if (processingStatus != ProcessingStatus.Postponed) { await RemovePostponedObject(expiredObject.Id); } } } catch (Exception e) { await LogException(e); } WaitHandle.WaitAny(new[] { cancellationToken.WaitHandle, pollNowEventHandle }, TimeSpan.FromSeconds(10)); } }
private async Task Run(CancellationToken cancellationToken) { try { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog($"{nameof(Distributor)} started", null)); await dataProcessingServiceLogger.Log(new DataProcessingServiceLog( $"{nameof(Distributor)} running for types '{processorDatabase.InputTypes.Aggregate((a, b) => a + ", " + b)}'", null)); } catch (Exception e) { Console.WriteLine(e); } try { while (!cancellationToken.IsCancellationRequested) { if (dataApiClient.IsAvailable()) { if (!dataApiClient.IsLoggedIn && !dataApiClient.RetryLogin().IsAuthenticated) { cancellationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(60)); continue; } try { var subscriptionNotifications = await dataApiClient.GetSubscribedObjects(); foreach (var subscriptionNotification in subscriptionNotifications) { if (cancellationToken.IsCancellationRequested) { break; } var dataType = subscriptionNotification.DataType; if (subscriptionNotification.ModificationType != DataModificationType.Deleted) { var exists = await dataApiClient.ExistsAsync( dataType, subscriptionNotification.DataObjectId); if (!exists) { await MarkAsProcessed(subscriptionNotification.Id); continue; } } try { var typeProcessors = processorDatabase.GetForType(dataType); switch (subscriptionNotification.ModificationType) { case DataModificationType.Created: case DataModificationType.Replaced: var typeObject = await LoadObject(subscriptionNotification); await ApplyProcessorsToObject( subscriptionNotification.ModificationType, dataType, subscriptionNotification.DataObjectId, typeObject, typeProcessors); break; case DataModificationType.Deleted: await ApplyProcessorsToObject( subscriptionNotification.ModificationType, dataType, subscriptionNotification.DataObjectId, null, typeProcessors); break; default: throw new ArgumentOutOfRangeException(); } await MarkAsProcessed(subscriptionNotification.Id); } catch (Exception e) { var logEntry = new DataProcessingServiceLog( $"Processing of '{dataType}' with ID '{subscriptionNotification.DataObjectId}' failed: {e.Message}", new ExecutionSummaryLogEntryDetails( DataProcessingServiceExecutorType.Processor, "Unknown", 0.To(Unit.Second), isError: true, isWorkDone: false, inputDataObjectId: subscriptionNotification.DataObjectId, inputTypeName: dataType)); await dataProcessingServiceLogger.Log(logEntry); } } } catch (Exception e) { var logEntry = new DataProcessingServiceLog( $"Processing of subscription notifications failed: {e.InnermostException().Message}", new CrashLogEntryDetails(nameof(Distributor), e.InnermostException().Message)); await dataProcessingServiceLogger.Log(logEntry); } } pollNowEventHandle.Reset(); WaitHandle.WaitAny(new[] { cancellationToken.WaitHandle, pollNowEventHandle }, PollInterval); } } catch (Exception e) { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog( $"Distributor crashed: {e.InnermostException().Message}", new CrashLogEntryDetails(nameof(Distributor), e.InnermostException().Message))); } try { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog($"{nameof(Distributor)} stopped", null)); } catch { // Ignore logging errors } }
private async Task Run(CancellationToken cancellationToken) { try { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog($"{nameof(PeriodicTasksRunner)} started", null)); await dataProcessingServiceLogger.Log(new DataProcessingServiceLog( $"{nameof(PeriodicTasksRunner)} running for " + $"'{taskDatabase.Tasks.Select(task => task.DisplayName).Aggregate((a, b) => a + ", " + b)}'", null)); } catch { // Ignore logging errors } while (!cancellationToken.IsCancellationRequested) { if (!dataApiClient.IsAvailable()) { cancellationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(60)); continue; } if (!dataApiClient.IsLoggedIn && !dataApiClient.RetryLogin().IsAuthenticated) { cancellationToken.WaitHandle.WaitOne(TimeSpan.FromSeconds(60)); continue; } var nextTask = TakeNextTask(taskQueue); var waitTime = nextTask != null ? nextTask.ScheduledExecutionTime - DateTime.UtcNow : TimeSpan.FromSeconds(30); if (waitTime > TimeSpan.Zero) { cancellationToken.WaitHandle.WaitOne(waitTime); } if (nextTask == null) { continue; } try { await LogTaskStarting(nextTask); } catch { // Ignore. Failing log shouldn't affect task execution } var stopWatch = Stopwatch.StartNew(); bool isSuccess; bool isWorkDone = false; string summary; try { var executionResult = nextTask.Task.Action(cancellationToken).Result; isSuccess = executionResult.IsSuccess; isWorkDone = executionResult.IsWorkDone; summary = executionResult.Summary; } catch (Exception e) { isSuccess = false; summary = e.InnermostException().Message; } stopWatch.Stop(); try { await LogTaskCompleted(nextTask, summary, isSuccess, isWorkDone, stopWatch); } catch { // Ignore. Failing log shouldn't affect task execution } switch (nextTask.Task) { case IPeriodicTask periodicTask: taskQueue.Add(new ScheduledTask(nextTask.ScheduledExecutionTime.Add(periodicTask.Period), periodicTask)); break; case IDailyTask dailyTask: var tomorrowSameTime = nextTask.ScheduledExecutionTime.AddDays(1); taskQueue.Add(new ScheduledTask(tomorrowSameTime, dailyTask)); break; } } try { await dataProcessingServiceLogger.Log(new DataProcessingServiceLog($"{nameof(PeriodicTasksRunner)} stopped", null)); } catch { // Ignore logging errors } }