Queue Attribute stopping Recurring Job from being Enqueued

I have two BackgroundJobServers set up as follows:

backgroundJobServer.Add(new BackgroundJobServer(new BackgroundJobServerOptions {
      ServerName = String.Format("{0}:Default", Environment.MachineName)
    }));

backgroundJobServer.Add(new BackgroundJobServer(new BackgroundJobServerOptions {
     ServerName = String.Format("{0}:JobAtATime", Environment.MachineName),
     WorkerCount = 1,
     Queues = new[] { "JobAtATime" }
   }));

I can see these both of these in my list of Servers, with the correct Server Name and Worker Count, so I presume they should be working as expected.

I also have the the following Recurring Jobs:

RecurringJob.AddOrUpdate<TaskA>("TaskA", j => j.DoSomething(), Cron.Minutely)
RecurringJob.AddOrUpdate<TaskB>("TaskB", j => j.DoSomething(), Cron.Minutely)
RecurringJob.AddOrUpdate<TaskC>("TaskC", j => j.DoSomething(), Cron.Minutely);

If I mark up one of my tasks with the Queue Attribute:

public class TaskA {
    [Queue("JobAtATime")]
    public void DoSomething() {
        //Do Something
    }
}

I’m finding that the Job is never Enqueued and all other recurring Jobs that occur after it are no longer Enqueued either.

I don’t have any visible errors here, as far as I can tell, but when I remove the Queue attribute my Recurring Jobs start Enqueuing again on the Default queue.

Am I missing something obvious here…?

For reference, I’m running Hangfire 1.4.1, using SqlServerStorage, my JobActivator uses Windsor to resolve dependancies and I use the DisableConcurrentExecutionAttribute in the GlobalJobFilters.

If there’s any relevant detail in my setup I may have missed in this post, please let me know.

Thanks!

EDIT:

If it’s of any use, the Job with the QueueAttribute seems to be inserted in the Job Table with StateId and StateName set to null.

Looks like there is an exception when trying to insert a new job. Do you have any logs? Here is how to configure the logging – http://docs.hangfire.io/en/latest/configuration/configuring-logging.html.

I use Elmah in my application and not seeing any errors logged for this particular problem.

If you refer to my edit, I can see the Job is being inserted in to the Job Table with the StateId and StateName set to null…?

If you refer to my edit, I can see the Job is being inserted in to the Job Table with the StateId and StateName set to null…?

Yep, this tells us there was a problem, because there should be a state change right after adding a new record. Please try to add Elmah log provider explicitly with a bit lower log level:

GlobalConfiguration.Configuration.UseElmahLogProvider(LogLevel.Warning);

Ah! Good call on adding the Elmah log provider explicitly, the error is immediately obvious:

System.ArgumentException: The queue name must consist of lowercase letters, digits and underscore characters only. Given: ‘JobAtATime’.

Changing my attribute to lower case alleviates the problem and my recurring Job is now Enqueuing again.

If attributes absolutely have to be lower case maybe it should be documented? I wouldn’t have intuitively guessed this!

Thanks for your help and for the fantasic product! :smile:

Debug
Error occurred during execution of 'Recurring Job Scheduler' component. Execution will be retried (attempt 1 of 2147483647) in 00:00:00 seconds.

Hangfire.Client.CreateJobFailedException: Job creation process has bee failed. See inner exception for details ---> System.ArgumentException: The queue name must consist of lowercase letters, digits and underscore characters only. Given: 'JobAtATime'.
Parameter name: value
   at Hangfire.States.EnqueuedState.set_Queue(String value)
   at Hangfire.QueueAttribute.OnStateElection(ElectStateContext context)
   at Hangfire.States.DefaultStateChangeProcess.ElectState(IStorageConnection connection, ElectStateContext context)
   at Hangfire.States.StateMachine.ChangeState(StateContext context, IState toState, String oldStateName)
   at Hangfire.States.StateMachine.CreateJob(Job job, IDictionary`2 parameters, IState state)
   at Hangfire.Client.DefaultJobCreationProcess.<>c__DisplayClass9.<CreateWithFilters>b__6()
   at Hangfire.Client.DefaultJobCreationProcess.InvokeClientFilter(IClientFilter filter, CreatingContext preContext, Func`1 continuation)
   at Hangfire.Client.DefaultJobCreationProcess.<>c__DisplayClass9.<>c__DisplayClassb.<CreateWithFilters>b__8()
   at Hangfire.Client.DefaultJobCreationProcess.CreateWithFilters(CreateContext context, IJobCreator creator, IEnumerable`1 filters)
   at Hangfire.Client.DefaultJobCreationProcess.Run(CreateContext context, IJobCreator creator)
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   --- End of inner exception stack trace ---
   at Hangfire.BackgroundJobClient.Create(Job job, IState state)
   at Hangfire.Server.RecurringJobScheduler.TryScheduleJob(IStorageConnection connection, String recurringJobId, Dictionary`2 recurringJob)
   at Hangfire.Server.RecurringJobScheduler.Execute(CancellationToken cancellationToken)
   at Hangfire.Server.AutomaticRetryServerComponentWrapper.ExecuteWithAutomaticRetry(CancellationToken cancellationToken)

Can you submit a PR for this? You can do this by going to the corresponding documentation page and clicking the Edit on GitHub button. You can highlight your message using the following format:

.. admonition:: My Header
   :class: note

   blablabla

I’m also thinking about making LogLevel.Warning the default level for Elmah. What do you think?

Can do!

Personally, I think it would help to weed out small issues like this - seeing this in Elmah would have made getting to the bottom of this very easy, but obviously I can’t speak for everyone!

Hi

FYI. If you don’t have logging configured, you will see the same message in the Windows Application event log.

Thanks - Adam