From 616fd73ea8ae793d726098ae11c2ff383f87bdb9 Mon Sep 17 00:00:00 2001 From: Rasmus Mikkelsen Date: Sat, 11 Oct 2025 16:30:18 +0200 Subject: [PATCH 1/3] Fix backward compatibility with 0.x --- ...fireJobRunnerBackwardCompatibilityTests.cs | 99 +++++++++++++++++++ .../Integration/HangfireJobRunner.cs | 13 +++ .../Integration/IHangfireJobRunner.cs | 9 ++ 3 files changed, 121 insertions(+) create mode 100644 Source/EventFlow.Hangfire.Tests/Integration/HangfireJobRunnerBackwardCompatibilityTests.cs diff --git a/Source/EventFlow.Hangfire.Tests/Integration/HangfireJobRunnerBackwardCompatibilityTests.cs b/Source/EventFlow.Hangfire.Tests/Integration/HangfireJobRunnerBackwardCompatibilityTests.cs new file mode 100644 index 000000000..965416e00 --- /dev/null +++ b/Source/EventFlow.Hangfire.Tests/Integration/HangfireJobRunnerBackwardCompatibilityTests.cs @@ -0,0 +1,99 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2025 Rasmus Mikkelsen +// https://github.com/eventflow/EventFlow +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System.Threading; +using System.Threading.Tasks; +using EventFlow.Hangfire.Integration; +using EventFlow.Jobs; +using NUnit.Framework; +using Shouldly; + +namespace EventFlow.Hangfire.Tests.Integration +{ + /// + /// Exercises the legacy Hangfire job runner signatures removed in EventFlow 1.x to ensure + /// that jobs enqueued by EventFlow.Hangfire 0.x still deserialize and execute via the + /// forwarding overloads introduced to address issue #1109. + /// + [TestFixture] + public class HangfireJobRunnerBackwardCompatibilityTests + { + private sealed class RecordingJobRunner : IJobRunner + { + public (string JobName, int Version, string Job, CancellationToken CancellationToken)? LastCall { get; private set; } + + public Task ExecuteAsync(string jobName, int version, string json, CancellationToken cancellationToken) + { + LastCall = (jobName, version, json, cancellationToken); + return Task.CompletedTask; + } + + public void Reset() + { + LastCall = null; + } + } + + [Test] + public void OldJobRunnerSignatureIsStillExposed() + { + var methodInfo = typeof(IHangfireJobRunner).GetMethod( + "ExecuteAsync", + new[] + { + typeof(string), + typeof(string), + typeof(int), + typeof(string), + typeof(string), + }); + + methodInfo.ShouldNotBeNull(); + } + + [Test] + public async Task OldSignatureDelegatesToModernImplementation() + { + var recordingJobRunner = new RecordingJobRunner(); + var hangfireJobRunner = new HangfireJobRunner(recordingJobRunner); + + #pragma warning disable CS0618 + await hangfireJobRunner.ExecuteAsync("display", "job", 7, "payload").ConfigureAwait(false); + + recordingJobRunner.LastCall.ShouldNotBeNull(); + recordingJobRunner.LastCall.Value.JobName.ShouldBe("job"); + recordingJobRunner.LastCall.Value.Version.ShouldBe(7); + recordingJobRunner.LastCall.Value.Job.ShouldBe("payload"); + recordingJobRunner.LastCall.Value.CancellationToken.ShouldBe(CancellationToken.None); + + recordingJobRunner.Reset(); + + await hangfireJobRunner.ExecuteAsync("display", "job", 7, "payload", "queue").ConfigureAwait(false); + #pragma warning restore CS0618 + + recordingJobRunner.LastCall.ShouldNotBeNull(); + recordingJobRunner.LastCall.Value.JobName.ShouldBe("job"); + recordingJobRunner.LastCall.Value.Version.ShouldBe(7); + recordingJobRunner.LastCall.Value.Job.ShouldBe("payload"); + } + } +} diff --git a/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs b/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs index dc4ac5ae1..3f7e9cbaf 100644 --- a/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs +++ b/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs @@ -20,6 +20,7 @@ // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +using System; using System.Threading; using System.Threading.Tasks; using EventFlow.Jobs; @@ -36,6 +37,18 @@ public HangfireJobRunner( _jobRunner = jobRunner; } + [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] + public Task ExecuteAsync(string displayName, string jobName, int version, string job) + { + return ExecuteAsync(jobName, version, job); + } + + [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] + public Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName) + { + return ExecuteAsync(jobName, version, job); + } + public Task ExecuteAsync(string jobName, int version, string job) { return _jobRunner.ExecuteAsync(jobName, version, job, CancellationToken.None); diff --git a/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs b/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs index e2eaaa6cc..d91b2b1b3 100644 --- a/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs +++ b/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs @@ -20,6 +20,7 @@ // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +using System; using System.ComponentModel; using System.Threading.Tasks; @@ -27,6 +28,14 @@ namespace EventFlow.Hangfire.Integration { public interface IHangfireJobRunner { + [Obsolete("Use ExecuteAsync(string jobName, int version, string job).")] + [DisplayName("{0}")] + Task ExecuteAsync(string displayName, string jobName, int version, string job); + + [Obsolete("Use ExecuteAsync(string jobName, int version, string job).")] + [DisplayName("{0}")] + Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName); + [DisplayName("{0}")] Task ExecuteAsync(string jobName, int version, string job); } From 487dc65b15f613a772ca485beb245401363549c2 Mon Sep 17 00:00:00 2001 From: Rasmus Mikkelsen Date: Sat, 11 Oct 2025 16:38:55 +0200 Subject: [PATCH 2/3] Update Obsolete attribute messages for clarity --- Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs b/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs index d91b2b1b3..f2ff14882 100644 --- a/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs +++ b/Source/EventFlow.Hangfire/Integration/IHangfireJobRunner.cs @@ -28,15 +28,15 @@ namespace EventFlow.Hangfire.Integration { public interface IHangfireJobRunner { - [Obsolete("Use ExecuteAsync(string jobName, int version, string job).")] + [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] [DisplayName("{0}")] Task ExecuteAsync(string displayName, string jobName, int version, string job); - [Obsolete("Use ExecuteAsync(string jobName, int version, string job).")] + [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] [DisplayName("{0}")] Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName); [DisplayName("{0}")] Task ExecuteAsync(string jobName, int version, string job); } -} \ No newline at end of file +} From e665739b5c0cd2d3a2b668565674c22c1a031497 Mon Sep 17 00:00:00 2001 From: Rasmus Mikkelsen Date: Sat, 11 Oct 2025 16:39:51 +0200 Subject: [PATCH 3/3] Suppress warnings for obsolete ExecuteAsync parameters Suppress unused parameter warnings for displayName and queueName in obsolete methods. --- Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs b/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs index 3f7e9cbaf..8463b6c4c 100644 --- a/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs +++ b/Source/EventFlow.Hangfire/Integration/HangfireJobRunner.cs @@ -40,12 +40,15 @@ public HangfireJobRunner( [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] public Task ExecuteAsync(string displayName, string jobName, int version, string job) { + _ = displayName; return ExecuteAsync(jobName, version, job); } [Obsolete("For backwards compatibility with jobs enqueued before EventFlow 1.x. Use ExecuteAsync(string jobName, int version, string job).")] public Task ExecuteAsync(string displayName, string jobName, int version, string job, string queueName) { + _ = displayName; + _ = queueName; return ExecuteAsync(jobName, version, job); } @@ -54,4 +57,4 @@ public Task ExecuteAsync(string jobName, int version, string job) return _jobRunner.ExecuteAsync(jobName, version, job, CancellationToken.None); } } -} \ No newline at end of file +}