I’ve had the same ‘problem’ and came up with the following solution:
- when configuring the server add a seperate queue per scheduler instance:
var serverOptions = new BackgroundJobServerOptions()
{
ServerName = GetSchedulerInstanceServerName(),
Queues = new[] { InstanceName, "Default" } //<==instance name is some static property
};
where InstanceName
is something unique to the server (e.g. the hostname + port)
- Add a jobfilter which extracts the queue from a job parameter:
internal class UseQueueFromParameterAttribute: JobFilterAttribute, IElectStateFilter
{
/// <summary>
/// Initializes a new instance of the <see cref="QueueAttribute"/> class
/// using the specified queue name.
/// </summary>
/// <param name="queue">Queue name.</param>
public UseQueueFromParameterAttribute(int parameterIndex)
{
this.ParameterIndex = parameterIndex;
}
public int ParameterIndex { get; private set; }
public void OnStateElection(ElectStateContext context)
{
var enqueuedState = context.CandidateState as EnqueuedState;
if (enqueuedState != null)
{
enqueuedState.Queue = context.Job.Arguments[ParameterIndex].Replace("\"",string.Empty);
}
}
}
Example usage:
internal class MaintenanceJob
{
[UseQueueFromParameter(0)] //extracts the queuename from parameter with index 0
public void Execute(string queuename)
{
//do some maintenance on the server
}
}
//now enqueue the job using the statically configured instance name
BackgroundJob.Enqueue<MaintenanceJob(x=>x.Execute(InstanceName));
EDIT:
please keep in mind that a queue name may only contain lowercase characters, numbers or underscores and has a maximum length of 20 characters…