public async Task GivenAcquireExportJobThrowsException_WhenExecuted_ThenWeHaveADelayBeforeWeRetry() { _fhirOperationDataStore.AcquireExportJobsAsync( DefaultMaximumNumberOfConcurrentJobAllowed, DefaultJobHeartbeatTimeoutThreshold, _cancellationToken) .ThrowsForAnyArgs <Exception>(); _cancellationTokenSource.CancelAfter(DefaultJobPollingFrequency * 1.25); await _exportJobWorker.ExecuteAsync(_cancellationToken); // Assert that we received only one call to AcquireExportJobsAsync await _fhirOperationDataStore.ReceivedWithAnyArgs(1).AcquireExportJobsAsync(Arg.Any <ushort>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()); }
public async Task ExecuteAsync(CancellationToken cancellationToken) { var runningTasks = new List <Task>(); while (!cancellationToken.IsCancellationRequested) { try { // Remove all completed tasks. runningTasks.RemoveAll(task => task.IsCompleted); // Get list of available jobs. if (runningTasks.Count < _exportJobConfiguration.MaximumNumberOfConcurrentJobsAllowed) { IReadOnlyCollection <ExportJobOutcome> jobs = await _fhirOperationDataStore.AcquireExportJobsAsync( _exportJobConfiguration.MaximumNumberOfConcurrentJobsAllowed, _exportJobConfiguration.JobHeartbeatTimeoutThreshold, cancellationToken); runningTasks.AddRange(jobs.Select(job => _exportJobTaskFactory().ExecuteAsync(job.JobRecord, job.ETag, cancellationToken))); } await Task.Delay(_exportJobConfiguration.JobPollingFrequency, cancellationToken); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // Cancel requested. } catch (Exception ex) { // The job failed. _logger.LogError(ex, "Unhandled exception in the worker."); } } }
private async Task <IReadOnlyCollection <ExportJobOutcome> > AcquireExportJobsAsync( ushort maximumNumberOfConcurrentJobAllowed = 1, TimeSpan?jobHeartbeatTimeoutThreshold = null) { if (jobHeartbeatTimeoutThreshold == null) { jobHeartbeatTimeoutThreshold = TimeSpan.FromMinutes(1); } return(await _operationDataStore.AcquireExportJobsAsync( maximumNumberOfConcurrentJobAllowed, jobHeartbeatTimeoutThreshold.Value, CancellationToken.None)); }
private void SetupOperationDataStore( ExportJobOutcome job, ushort maximumNumberOfConcurrentJobsAllowed = DefaultMaximumNumberOfConcurrentJobAllowed, TimeSpan?jobHeartbeatTimeoutThreshold = null, TimeSpan?jobPollingFrequency = null) { if (jobHeartbeatTimeoutThreshold == null) { jobHeartbeatTimeoutThreshold = DefaultJobHeartbeatTimeoutThreshold; } if (jobPollingFrequency == null) { jobPollingFrequency = DefaultJobPollingFrequency; } _fhirOperationDataStore.AcquireExportJobsAsync( maximumNumberOfConcurrentJobsAllowed, jobHeartbeatTimeoutThreshold.Value, _cancellationToken) .Returns(new[] { job }); }