public void UpdateStatus(JobStatus newStatus, string progressMessage, params object[] args) { var logMessage = FormatMessage(newStatus == JobStatus.Failed ? "ERROR" : "INFO", progressMessage, args); _jobInfo.CurrentStatus = newStatus; _jobRepository.UpdateJobInfoAsync(_jobInfo); NotifyStatusAsync(newStatus); NotifyAsync(logMessage); if (newStatus == JobStatus.Failed) { _log.Error(logMessage); } else { _log.Information(logMessage); } _fullLog.AppendLine(logMessage); }
private async Task ProcessJob(IJobStore jobStore, JobInfo jobInfo) { var progressLogFactory = Services.GetRequiredService <IProgressLogFactory>(); var progressLog = await progressLogFactory.MakeProgressLogForJobAsync(jobInfo); var logStore = Services.GetService <ILogStore>(); try { var jobLogger = Log.ForContext("JobId", jobInfo.JobId); jobLogger.Information("Processing Job {JobId} - {JobType}", jobInfo.JobId, jobInfo.JobType); jobLogger.Debug("Retrieving user account for {UserId}", jobInfo.UserId); var userRepo = Services.GetRequiredService <IUserStore>(); var userAccount = await userRepo.GetUserAccountAsync(jobInfo.UserId); // TODO: Should encapsulate this logic plus basic job info validation into its own processor factory class (issue #83) jobLogger.Debug("Creating job processor for job type {JobType}", jobInfo.JobType); IDataDockProcessor processor; switch (jobInfo.JobType) { case JobType.Import: { var cmdProcessorFactory = Services.GetRequiredService <IGitCommandProcessorFactory>(); processor = new ImportJobProcessor( Services.GetRequiredService <WorkerConfiguration>(), cmdProcessorFactory.MakeGitCommandProcessor(progressLog), Services.GetRequiredService <IGitHubClientFactory>(), Services.GetRequiredService <IDatasetStore>(), Services.GetRequiredService <IFileStore>(), Services.GetRequiredService <IOwnerSettingsStore>(), Services.GetRequiredService <IRepoSettingsStore>(), Services.GetRequiredService <IDataDockRepositoryFactory>(), Services.GetRequiredService <IDataDockUriService>()); break; } case JobType.Delete: { var cmdProcessorFactory = Services.GetRequiredService <IGitCommandProcessorFactory>(); processor = new DeleteDatasetProcessor( Services.GetRequiredService <WorkerConfiguration>(), cmdProcessorFactory.MakeGitCommandProcessor(progressLog), Services.GetRequiredService <IGitHubClientFactory>(), Services.GetRequiredService <IOwnerSettingsStore>(), Services.GetRequiredService <IRepoSettingsStore>(), Services.GetRequiredService <IDatasetStore>(), Services.GetRequiredService <IDataDockRepositoryFactory>()); break; } case JobType.SchemaCreate: processor = new ImportSchemaProcessor( Services.GetRequiredService <WorkerConfiguration>(), Services.GetRequiredService <ISchemaStore>(), Services.GetRequiredService <IFileStore>()); break; case JobType.SchemaDelete: processor = new DeleteSchemaProcessor(Services.GetRequiredService <ISchemaStore>()); break; default: throw new WorkerException($"Could not process job of type {jobInfo.JobType}"); } // Log start jobLogger.Debug("Start job processor"); jobInfo.StartedAt = DateTime.UtcNow; jobInfo.CurrentStatus = JobStatus.Running; await jobStore.UpdateJobInfoAsync(jobInfo); progressLog.UpdateStatus(JobStatus.Running, "Job processing started"); await processor.ProcessJob(jobInfo, userAccount, progressLog); // Log end jobLogger.Information("Job processing completed"); var logId = await logStore.AddLogAsync(jobInfo.OwnerId, jobInfo.RepositoryId, jobInfo.JobId, progressLog.GetLogText()); jobInfo.CurrentStatus = JobStatus.Completed; jobInfo.CompletedAt = DateTime.UtcNow; jobInfo.LogId = logId; await jobStore.UpdateJobInfoAsync(jobInfo); progressLog.UpdateStatus(jobInfo.CurrentStatus, "Job completed"); } catch (Exception ex) { if (ex is WorkerException wex) { progressLog.UpdateStatus(JobStatus.Failed, wex.Message); Log.Error(wex, "WorkerException raised for job {JobId}", jobInfo.JobId); } else { Log.Error(ex, "Job processing failed for job {JobId}", jobInfo.JobId); } var logId = await logStore.AddLogAsync(jobInfo.OwnerId, jobInfo.RepositoryId, jobInfo.JobId, progressLog.GetLogText()); jobInfo.LogId = logId; jobInfo.CurrentStatus = JobStatus.Failed; jobInfo.CompletedAt = DateTime.UtcNow; await jobStore.UpdateJobInfoAsync(jobInfo); progressLog.UpdateStatus(JobStatus.Failed, "Job processing failed"); } }