Skip to content

Commit c2221a4

Browse files
authored
Merge pull request #1129 from eventflow/handfire-bug-compatibility
Fix: Hangfre backward compatibility with 0.x
2 parents aa95145 + 8a880df commit c2221a4

File tree

3 files changed

+126
-2
lines changed

3 files changed

+126
-2
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2015-2025 Rasmus Mikkelsen
4+
// https://github.com/eventflow/EventFlow
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
7+
// this software and associated documentation files (the "Software"), to deal in
8+
// the Software without restriction, including without limitation the rights to
9+
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10+
// the Software, and to permit persons to whom the Software is furnished to do so,
11+
// subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in all
14+
// copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18+
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19+
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20+
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
23+
using System.Threading;
24+
using System.Threading.Tasks;
25+
using EventFlow.Hangfire.Integration;
26+
using EventFlow.Jobs;
27+
using NUnit.Framework;
28+
using Shouldly;
29+
30+
namespace EventFlow.Hangfire.Tests.Integration
31+
{
32+
/// <summary>
33+
/// Exercises the legacy Hangfire job runner signatures removed in EventFlow 1.x to ensure
34+
/// that jobs enqueued by EventFlow.Hangfire 0.x still deserialize and execute via the
35+
/// forwarding overloads introduced to address issue #1109.
36+
/// </summary>
37+
[TestFixture]
38+
public class HangfireJobRunnerBackwardCompatibilityTests
39+
{
40+
private sealed class RecordingJobRunner : IJobRunner
41+
{
42+
public (string JobName, int Version, string Job, CancellationToken CancellationToken)? LastCall { get; private set; }
43+
44+
public Task ExecuteAsync(string jobName, int version, string json, CancellationToken cancellationToken)
45+
{
46+
LastCall = (jobName, version, json, cancellationToken);
47+
return Task.CompletedTask;
48+
}
49+
50+
public void Reset()
51+
{
52+
LastCall = null;
53+
}
54+
}
55+
56+
[Test]
57+
public void OldJobRunnerSignatureIsStillExposed()
58+
{
59+
var methodInfo = typeof(IHangfireJobRunner).GetMethod(
60+
"ExecuteAsync",
61+
new[]
62+
{
63+
typeof(string),
64+
typeof(string),
65+
typeof(int),
66+
typeof(string),
67+
typeof(string),
68+
});
69+
70+
methodInfo.ShouldNotBeNull();
71+
}
72+
73+
[Test]
74+
public async Task OldSignatureDelegatesToModernImplementation()
75+
{
76+
var recordingJobRunner = new RecordingJobRunner();
77+
var hangfireJobRunner = new HangfireJobRunner(recordingJobRunner);
78+
79+
#pragma warning disable CS0618
80+
await hangfireJobRunner.ExecuteAsync("display", "job", 7, "payload").ConfigureAwait(false);
81+
82+
recordingJobRunner.LastCall.ShouldNotBeNull();
83+
recordingJobRunner.LastCall.Value.JobName.ShouldBe("job");
84+
recordingJobRunner.LastCall.Value.Version.ShouldBe(7);
85+
recordingJobRunner.LastCall.Value.Job.ShouldBe("payload");
86+
recordingJobRunner.LastCall.Value.CancellationToken.ShouldBe(CancellationToken.None);
87+
88+
recordingJobRunner.Reset();
89+
90+
await hangfireJobRunner.ExecuteAsync("display", "job", 7, "payload", "queue").ConfigureAwait(false);
91+
#pragma warning restore CS0618
92+
93+
recordingJobRunner.LastCall.ShouldNotBeNull();
94+
recordingJobRunner.LastCall.Value.JobName.ShouldBe("job");
95+
recordingJobRunner.LastCall.Value.Version.ShouldBe(7);
96+
recordingJobRunner.LastCall.Value.Job.ShouldBe("payload");
97+
}
98+
}
99+
}

Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2121
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222

23+
using System;
2324
using System.Threading;
2425
using System.Threading.Tasks;
2526
using EventFlow.Jobs;
@@ -36,9 +37,24 @@ public HangfireJobRunner(
3637
_jobRunner = jobRunner;
3738
}
3839

40+
[Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")]
41+
public Task ExecuteAsync(string displayName, string jobName, int version, string job)
42+
{
43+
_ = displayName;
44+
return ExecuteAsync(jobName, version, job);
45+
}
46+
47+
[Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")]
48+
public Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName)
49+
{
50+
_ = displayName;
51+
_ = queueName;
52+
return ExecuteAsync(jobName, version, job);
53+
}
54+
3955
public Task ExecuteAsync(string jobName, int version, string job)
4056
{
4157
return _jobRunner.ExecuteAsync(jobName, version, job, CancellationToken.None);
4258
}
4359
}
44-
}
60+
}

Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,23 @@
2020
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2121
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222

23+
using System;
2324
using System.ComponentModel;
2425
using System.Threading.Tasks;
2526

2627
namespace EventFlow.Hangfire.Integration
2728
{
2829
public interface IHangfireJobRunner
2930
{
31+
[Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")]
32+
[DisplayName("{0}")]
33+
Task ExecuteAsync(string displayName, string jobName, int version, string job);
34+
35+
[Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")]
36+
[DisplayName("{0}")]
37+
Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName);
38+
3039
[DisplayName("{0}")]
3140
Task ExecuteAsync(string jobName, int version, string job);
3241
}
33-
}
42+
}

0 commit comments

Comments
 (0)