Search code examples
hangfirelinqpadhangfire-sqllinqpad7

Static Hangfire RecurringJob methods in LINQPad are not behaving


I have a script in LINQPad that looks like this:

var serverMode = EnvironmentType.EWPROD;
var jobToSchedule = JobType.ABC;
var hangfireCs = GetConnectionString(serverMode);
JobStorage.Current = new SqlServerStorage(hangfireCs);

Action<string, string, XElement> createOrReplaceJob =
    (jobName, cronExpression, inputPackage) =>
    {
        RecurringJob.RemoveIfExists(jobName);
        RecurringJob.AddOrUpdate(
            jobName,
             () => new BTR.Evolution.Hangfire.Schedulers.JobInvoker().Invoke(
                     jobName,
                     inputPackage,
                     null,
                     JobCancellationToken.Null),
            cronExpression, TimeZoneInfo.Local);
    };

// psuedo code to prepare inputPackage for client ABC...

createOrReplaceJob("ABC.CustomReport.SurveyResults", "0 2 * * *", inputPackage);

JobStorage.Current.GetConnection().GetRecurringJobs().Where( j => j.Id.StartsWith( jobToSchedule.ToString() ) ).Dump( "Scheduled Jobs" );

I have to schedule in both QA and PROD. To do that, I toggle the serverMode variable and run it once for EWPROD and once for EWQA. This all worked fine until recently, and I don't know exactly when it changed unfortunately because I don't always have to run in both environments.

I did purchase/install LINQPad 7 two days ago to look at some C# 10 features and I'm not sure if that affected it.

But here is the problem/flow:

  1. Run it for EWQA and everything works.
  2. Run it for EWPROD and the script (Hangfire components) seem to run in a mix of QA and PROD.

When I'm running it the 'second time' in EWPROD I've confirmed:

  1. The hangfireCs (connection string) is right (pointing to PROD) and it is assigned to JobStorage.Current
  2. The query at the end of the script, JobStorage.Current.GetConnection().GetRecurringJobs() uses the right connection.
  3. The RecurringJob.* methods inside the createOrReplaceJob Action use the connection from the previous run (i.e. EWQA). If I monitor my QA Hangfire db, I see the job removed and added.

Temporary workaround:

  1. Run it for EWQA and everything works.
  2. Restart LINQPad or use 'Cancel and Reset All Queries' method
  3. Run it for EWPROD and now everything works.

So I'm at a loss of where the issue might lie. I feel like my upgrade/install of LINQPad7 might be causing problems, but I'm not sure if there is a different way to make the RecurringJob.* static methods use the 'updated' connection string.

Any ideas on why the restart or reset is now needed?

LINQPad - 5.44.02 Hangfire.Core - 1.7.17 Hangfire.SqlServer - 1.7.17


Solution

  • This is caused by your script (or a library that you call) caching something statically, and not cleaning up between executions.

    Either clear/dispose objects when you're done (e.g., JobStorage.Current?) or tell LINQPad not to re-use the process between executions, by adding Util.NewProcess=true; to your script.