예제 #1
0
 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));
            }
        }
예제 #3
0
        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
            }
        }
예제 #4
0
        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
            }
        }