Skip to content

Commit

Permalink
If jobs implement IAsyncLifetime or IAsyncDisposable then call the me…
Browse files Browse the repository at this point in the history
…thods in JobRunner.
  • Loading branch information
ejsmith committed Apr 26, 2019
1 parent fc16989 commit 2fbd14f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 26 deletions.
72 changes: 46 additions & 26 deletions src/Foundatio/Jobs/JobRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,33 +108,53 @@ public async Task<bool> RunAsync(CancellationToken cancellationToken = default)
if (_logger.IsEnabled(LogLevel.Information))
_logger.LogInformation("Starting job type {JobName} on machine {MachineName}...", _jobName, Environment.MachineName);

if (_options.InitialDelay.HasValue && _options.InitialDelay.Value > TimeSpan.Zero)
await SystemClock.SleepAsync(_options.InitialDelay.Value, cancellationToken).AnyContext();

if (_options.RunContinuous && _options.InstanceCount > 1) {
var tasks = new List<Task>(_options.InstanceCount);
for (int i = 0; i < _options.InstanceCount; i++) {
tasks.Add(Task.Run(async () => {
try {
var jobInstance = _options.JobFactory();
await jobInstance.RunContinuousAsync(_options.Interval, _options.IterationLimit, cancellationToken).AnyContext();
} catch (TaskCanceledException) {
} catch (Exception ex) {
if (_logger.IsEnabled(LogLevel.Error))
_logger.LogError(ex, "Error running job instance: {Message}", ex.Message);
throw;
}
}, cancellationToken));
}

await Task.WhenAll(tasks).AnyContext();
} else if (_options.RunContinuous && _options.InstanceCount == 1) {
await job.RunContinuousAsync(_options.Interval, _options.IterationLimit, cancellationToken).AnyContext();
} else {
var result = await job.TryRunAsync(cancellationToken).AnyContext();
_logger.LogJobResult(result, _jobName);
var jobLifetime = job as IAsyncLifetime;
if (jobLifetime != null) {
if (_logger.IsEnabled(LogLevel.Information))
_logger.LogInformation("Initializing job lifetime {JobName} on machine {MachineName}...", _jobName, Environment.MachineName);
await jobLifetime.InitializeAsync().AnyContext();
if (_logger.IsEnabled(LogLevel.Information))
_logger.LogInformation("Done initializing job lifetime {JobName} on machine {MachineName}.", _jobName, Environment.MachineName);
}

return result.IsSuccess;
try {
if (_options.InitialDelay.HasValue && _options.InitialDelay.Value > TimeSpan.Zero)
await SystemClock.SleepAsync(_options.InitialDelay.Value, cancellationToken).AnyContext();

if (_options.RunContinuous && _options.InstanceCount > 1) {
var tasks = new List<Task>(_options.InstanceCount);
for (int i = 0; i < _options.InstanceCount; i++) {
tasks.Add(Task.Run(async () => {
try {
var jobInstance = _options.JobFactory();
await jobInstance.RunContinuousAsync(_options.Interval, _options.IterationLimit, cancellationToken).AnyContext();
} catch (TaskCanceledException) {
} catch (Exception ex) {
if (_logger.IsEnabled(LogLevel.Error))
_logger.LogError(ex, "Error running job instance: {Message}", ex.Message);
throw;
}
}, cancellationToken));
}

await Task.WhenAll(tasks).AnyContext();
} else if (_options.RunContinuous && _options.InstanceCount == 1) {
await job.RunContinuousAsync(_options.Interval, _options.IterationLimit, cancellationToken).AnyContext();
} else {
var result = await job.TryRunAsync(cancellationToken).AnyContext();
_logger.LogJobResult(result, _jobName);

return result.IsSuccess;
}
} finally {
var jobDisposable = job as IAsyncDisposable;
if (jobDisposable != null) {
if (_logger.IsEnabled(LogLevel.Information))
_logger.LogInformation("Disposing job lifetime {JobName} on machine {MachineName}...", _jobName, Environment.MachineName);
await jobDisposable.DisposeAsync().AnyContext();
if (_logger.IsEnabled(LogLevel.Information))
_logger.LogInformation("Done disposing job lifetime {JobName} on machine {MachineName}.", _jobName, Environment.MachineName);
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/Foundatio/Utility/IAsyncLifetime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;

namespace Foundatio.Utility {
public interface IAsyncLifetime : IAsyncDisposable {
Task InitializeAsync();
}
}

0 comments on commit 2fbd14f

Please sign in to comment.