Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 28 additions & 29 deletions src/Core/Jobs/BaseJobsHostedService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
๏ปฟusing System.Collections.Specialized;
using Bit.Core.Settings;
๏ปฟusing Bit.Core.Settings;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;

namespace Bit.Core.Jobs;
Expand Down Expand Up @@ -37,31 +35,32 @@ public BaseJobsHostedService(

public virtual async Task StartAsync(CancellationToken cancellationToken)
{
var props = new NameValueCollection
var fullName = GetType().FullName;
if (fullName == null)
{
{"quartz.serializer.type", "binary"},
};
throw new InvalidOperationException("Hosted service must have a valid type name.");
}
var schedulerBuilder = SchedulerBuilder.Create()
.WithName(fullName) // Ensure each project has a unique instanceName
.WithId("AUTO");

if (!string.IsNullOrEmpty(_globalSettings.SqlServer.JobSchedulerConnectionString))
{
// Ensure each project has a unique instanceName
props.Add("quartz.scheduler.instanceName", GetType().FullName);
props.Add("quartz.scheduler.instanceId", "AUTO");
props.Add("quartz.jobStore.type", "Quartz.Impl.AdoJobStore.JobStoreTX");
props.Add("quartz.jobStore.driverDelegateType", "Quartz.Impl.AdoJobStore.SqlServerDelegate");
props.Add("quartz.jobStore.useProperties", "true");
props.Add("quartz.jobStore.dataSource", "default");
props.Add("quartz.jobStore.tablePrefix", "QRTZ_");
props.Add("quartz.jobStore.clustered", "true");
props.Add("quartz.dataSource.default.provider", "SqlServer");
props.Add("quartz.dataSource.default.connectionString", _globalSettings.SqlServer.JobSchedulerConnectionString);
schedulerBuilder = schedulerBuilder.UsePersistentStore(options =>
{
options.UseProperties = true;
options.UseClustering();
options.UseBinarySerializer();
options.UseSqlServer(connectionString: _globalSettings.SqlServer.JobSchedulerConnectionString);
});
}

var factory = new StdSchedulerFactory(props);
var factory = schedulerBuilder.Build();
_scheduler = await factory.GetScheduler(cancellationToken);
_scheduler.JobFactory = new JobFactory(_serviceProvider);
_scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger),
GroupMatcher<JobKey>.AnyGroup());

_scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger), GroupMatcher<JobKey>.AnyGroup());

await _scheduler.Start(cancellationToken);

var jobKeys = new List<JobKey>();
Expand All @@ -81,23 +80,23 @@ public virtual async Task StartAsync(CancellationToken cancellationToken)
// There's a race condition when starting multiple containers simultaneously, retry until it succeeds..
try
{
var dupeT = await _scheduler.GetTrigger(trigger.Key);
var dupeT = await _scheduler.GetTrigger(trigger.Key, cancellationToken);
if (dupeT != null)
{
await _scheduler.RescheduleJob(trigger.Key, trigger);
await _scheduler.RescheduleJob(trigger.Key, trigger, cancellationToken);
}

var jobDetail = JobBuilder.Create(job)
.WithIdentity(job.FullName!)
.Build();

var dupeJ = await _scheduler.GetJobDetail(jobDetail.Key);
var dupeJ = await _scheduler.GetJobDetail(jobDetail.Key, cancellationToken);
if (dupeJ != null)
{
await _scheduler.DeleteJob(jobDetail.Key);
await _scheduler.DeleteJob(jobDetail.Key, cancellationToken);
}

await _scheduler.ScheduleJob(jobDetail, trigger);
await _scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
break;
}
catch (Exception e)
Expand All @@ -116,7 +115,7 @@ public virtual async Task StartAsync(CancellationToken cancellationToken)
}

// Delete old Jobs and Triggers
var existingJobKeys = await _scheduler.GetJobKeys(GroupMatcher<JobKey>.AnyGroup());
var existingJobKeys = await _scheduler.GetJobKeys(GroupMatcher<JobKey>.AnyGroup(), cancellationToken);

foreach (var key in existingJobKeys)
{
Expand All @@ -126,10 +125,10 @@ public virtual async Task StartAsync(CancellationToken cancellationToken)
}

_logger.LogInformation("Deleting old job with key {Key}", key);
await _scheduler.DeleteJob(key);
await _scheduler.DeleteJob(key, cancellationToken);
}

var existingTriggerKeys = await _scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup());
var existingTriggerKeys = await _scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup(), cancellationToken);

foreach (var key in existingTriggerKeys)
{
Expand All @@ -139,7 +138,7 @@ public virtual async Task StartAsync(CancellationToken cancellationToken)
}

_logger.LogInformation("Unscheduling old trigger with key {Key}", key);
await _scheduler.UnscheduleJob(key);
await _scheduler.UnscheduleJob(key, cancellationToken);
}
}

Expand Down
Loading