HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.18k stars 1.67k forks source link

[Hangfire.Core Bug] ContinueJobWith starts too early by default with Task #1639

Open hyperion-cs opened 4 years ago

hyperion-cs commented 4 years ago

@odinserj, Hello! Under certain standard conditions ContinueJobWith starts by default when the dependent job is still in PROCESSING state.

How to reproduce:

  1. When called ContinueJobWith with Action:
    _bjc.ContinueJobWith(jobId, () => Console.WriteLine("Continuation!"))

    The public static string ContinueJobWith([NotNull] this IBackgroundJobClient client, [NotNull] string parentId, [InstantHandle][NotNull] Expression<Action> methodCall); overload will be used, everything is fine. "Continue job" will only be executed when the dependent job is done (success/failed). 2 However, if you use a Func, such as this:

    Expression<Func<T, Task>> func = x => new Task(() => Console.WriteLine("Continuation!"));
    _bjc.ContinueJobWith(jobId, func);

    An overload of public static string ContinueJobWith<T>([NotNull] this IBackgroundJobClient client, [NotNull] string parentId, [InstantHandle][NotNull] Expression<Func<T, Task>> methodCall, [CanBeNull] IState nextState = null, JobContinuationOptions options = JobContinuationOptions.OnlyOnSucceededState); will be used.

It has nextState as null by default, which means that "continue job" will be started immediately after Hangfire.States.EnqueuedState. Thus, the default behavior is such that the job does not expect the job to finish FULL when using Func. In other words, if we want to use the Task, it doesn't work the way it should.

odinserj commented 4 years ago

Please tell me what version of Hangfire.Core you have, what storage package (and its version) you are using? Also, please post here the concrete minimal method that doesn't work as expected.

hyperion-cs commented 4 years ago

@odinserj, Hangfire.Core 1.7.10 Hangfire.PostgreSql 1.6.4.2

When I tried to collect the minimum method for you, I came across the fact that it was not so easy. In an isolated environment, everything works fine. Could it be that ContinueJobWith has already worked, but the storage provider has not yet managed to update the state + result? Or does ContinueJobWith work based on the data from the storage and take nothing from RAM/etc directly?