0

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

Terry
  • 2,148
  • 2
  • 32
  • 53
  • Have you tried to execute RecurringJob methods directly, e.g. not inside an anonymous callback? I don’t see anything related to Hangfire – yes, it uses static fields, but I have no idea why something is changed in the middle of execution. – odinserj Feb 15 '22 at 04:30

1 Answers1

0

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.

Joe Albahari
  • 30,118
  • 7
  • 80
  • 91
  • I will give it a try (`Util.NewProcess=true`), but this script has been used for last couple years without change. I don't think I've updated the Hangfire Nuget packages either, but I can't 100% guarantee that. – Terry Feb 14 '22 at 13:30