Skip to content

Commit 0de01fc

Browse files
committed
Merge branch 'main' into dev
2 parents 6c691d2 + 8e3a4d8 commit 0de01fc

14 files changed

Lines changed: 520 additions & 524 deletions

nuspecs/Hangfire.Core.nuspec

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ https://www.hangfire.io/
2323
Release notes are available in our blog https://www.hangfire.io/blog/
2424
Please see https://docs.hangfire.io/en/latest/upgrade-guides/upgrading-to-hangfire-1.8.html to learn how to upgrade.
2525
26+
1.8.21
27+
• Added – `FailedState.IncludeFileInfo` to optionally show/hide line numbers in exceptions in Failed state.
28+
• Changed – Include line numbers for exceptions by default when available.
29+
• Fixed – Portuguese (Brazil) translations in Strings.pt-BR.resx (by @pedro-cons).
30+
• Fixed – Static `BackgroundJob` class always acquires the most current `JobStorage.Current` instance.
31+
• Fixed – Static `RecurringJob` class always acquires the most current `JobStorage.Current` instance.
32+
2633
1.8.20
2734
• Fixed – Glyphicons from Bootstrap are not displaying after upgrading to version 1.8.19.
2835

nuspecs/Hangfire.SqlServer.nuspec

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
Release notes are available in our blog https://www.hangfire.io/blog/
1818
Please see https://docs.hangfire.io/en/latest/upgrade-guides/upgrading-to-hangfire-1.8.html to learn how to upgrade.
1919
20+
1.8.21
21+
• Added – `SqlServerStorageOptions.DisableTransactionScope` option for .NET Framework targets.
22+
• Project – Port Monitoring API tests from the Hangfire.InMemory storage for better coverage.
23+
• Project – Run tests for different targets in parallel with different databases.
24+
2025
1.8.19
2126
• Fixed – Sliding invisibility timeout isn't prolonged in lightweight servers, causing jobs to be restarted.
2227

nuspecs/Hangfire.nuspec

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ https://www.hangfire.io/
2323
Release notes are available in our blog https://www.hangfire.io/blog/
2424
Please see https://docs.hangfire.io/en/latest/upgrade-guides/upgrading-to-hangfire-1.8.html to learn how to upgrade.
2525
26+
1.8.21
27+
28+
Hangfire.Core
29+
30+
• Added – `FailedState.IncludeFileInfo` to optionally show/hide line numbers in exceptions in Failed state.
31+
• Changed – Include line numbers for exceptions by default when available.
32+
• Fixed – Portuguese (Brazil) translations in Strings.pt-BR.resx (by @pedro-cons).
33+
• Fixed – Static `BackgroundJob` class always acquires the most current `JobStorage.Current` instance.
34+
• Fixed – Static `RecurringJob` class always acquires the most current `JobStorage.Current` instance.
35+
36+
Hangfire.SqlServer
37+
38+
• Added – `SqlServerStorageOptions.DisableTransactionScope` option for .NET Framework targets.
39+
• Project – Port Monitoring API tests from the Hangfire.InMemory storage for better coverage.
40+
• Project – Run tests for different targets in parallel with different databases.
41+
2642
1.8.20
2743
2844
Hangfire.Core

samples/ConsoleSample/ConsoleSample.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net451</TargetFramework>
66
<UseRidGraph>true</UseRidGraph>
7+
<DebugType>full</DebugType>
78
</PropertyGroup>
89

910
<ItemGroup>

samples/ConsoleSample/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public static void Main()
2828
.UseDefaultCulture(CultureInfo.CurrentCulture)
2929
.UseSqlServerStorage(@"Server=.\;Database=Hangfire.Sample;Trusted_Connection=True;", new SqlServerStorageOptions
3030
{
31-
EnableHeavyMigrations = true
31+
EnableHeavyMigrations = true,
32+
DisableTransactionScope = true
3233
});
3334

3435
Console.WriteLine(SerializationHelper.Serialize(new ExceptionInfo(new OperationCanceledException()), SerializationOption.Internal));

src/Hangfire.Core/BackgroundJob.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,10 @@ namespace Hangfire
4444
/// <threadsafety static="true" instance="false" />
4545
public partial class BackgroundJob
4646
{
47-
private static readonly Lazy<IBackgroundJobClient> CachedClient
48-
= new Lazy<IBackgroundJobClient>(static () => new BackgroundJobClient(), LazyThreadSafetyMode.PublicationOnly);
49-
50-
private static readonly Func<IBackgroundJobClient> DefaultFactory
51-
= static () => CachedClient.Value;
47+
private static readonly Func<IBackgroundJobClient> DefaultFactory = static () => new BackgroundJobClient();
48+
private static readonly object ClientFactoryLock = new object();
5249

5350
private static Func<IBackgroundJobClient>? _clientFactory;
54-
private static readonly object ClientFactoryLock = new object();
5551

5652
internal static Func<IBackgroundJobClient> ClientFactory
5753
{

src/Hangfire.Core/Common/ShallowExceptionHelper.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,17 @@ public static void PreserveOriginalStackTrace(this Exception exception)
2828
{
2929
if (exception != null && !exception.Data.Contains(DataKey))
3030
{
31-
exception.Data.Add(DataKey, GetStackTraceNoFileInfo(exception));
31+
exception.Data.Add(DataKey, GetStackTrace(exception, includeFileInfo: false));
3232
}
3333
}
3434

35-
public static string ToStringWithOriginalStackTrace(this Exception exception, int? numLines)
35+
public static string ToStringWithOriginalStackTrace(this Exception exception, int? numLines, bool includeFileInfo)
3636
{
3737
if (exception == null) throw new ArgumentNullException(nameof(exception));
38-
39-
return GetFirstLines(ToStringHelper(exception, false), numLines);
38+
return GetFirstLines(ToStringHelper(exception, false, includeFileInfo), numLines);
4039
}
4140

42-
private static string ToStringHelper(Exception exception, bool isInner)
41+
private static string ToStringHelper(Exception exception, bool isInner, bool includeFileInfo)
4342
{
4443
var sb = new StringBuilder();
4544
sb.Append(exception.GetType().FullName);
@@ -49,11 +48,12 @@ private static string ToStringHelper(Exception exception, bool isInner)
4948
if (exception.InnerException != null)
5049
{
5150
sb.Append(" ---> ");
52-
sb.Append(ToStringHelper(exception.InnerException, true));
51+
sb.Append(ToStringHelper(exception.InnerException, true, includeFileInfo));
5352
}
5453
else sb.Append('\n');
5554

56-
var stackTrace = exception.Data.Contains(DataKey) ? (string?)exception.Data[DataKey] : GetStackTraceNoFileInfo(exception);
55+
var stackTrace = exception.Data.Contains(DataKey) ? (string?)exception.Data[DataKey] : GetStackTrace(exception, includeFileInfo);
56+
5757
if (!String.IsNullOrWhiteSpace(stackTrace))
5858
{
5959
sb.Append(stackTrace);
@@ -88,12 +88,12 @@ private static string ToStringHelper(Exception exception, bool isInner)
8888
}
8989
}
9090

91-
private static string GetStackTraceNoFileInfo(Exception ex)
91+
private static string GetStackTrace(Exception ex, bool includeFileInfo)
9292
{
9393
#if NETSTANDARD1_3
9494
return ex.StackTrace;
9595
#else
96-
return new System.Diagnostics.StackTrace(ex, fNeedFileInfo: false).ToString();
96+
return new System.Diagnostics.StackTrace(ex, includeFileInfo).ToString();
9797
#endif
9898
}
9999
}

src/Hangfire.Core/RecurringJob.cs

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,28 @@ namespace Hangfire
2525
{
2626
public static class RecurringJob
2727
{
28-
private static readonly Lazy<RecurringJobManager> Instance = new Lazy<RecurringJobManager>(
29-
static () => new RecurringJobManager(), LazyThreadSafetyMode.PublicationOnly);
28+
private static readonly Func<RecurringJobManager> DefaultFactory = static () => new RecurringJobManager();
29+
private static readonly object ManagerFactoryLock = new object();
30+
31+
private static Func<RecurringJobManager>? _managerFactory;
32+
33+
internal static Func<RecurringJobManager> ManagerFactory
34+
{
35+
get
36+
{
37+
lock (ManagerFactoryLock)
38+
{
39+
return _managerFactory ?? DefaultFactory;
40+
}
41+
}
42+
set
43+
{
44+
lock (ManagerFactoryLock)
45+
{
46+
_managerFactory = value;
47+
}
48+
}
49+
}
3050

3151
[Obsolete("Please use an overload with the explicit recurringJobId parameter and RecurringJobOptions instead. Will be removed in 2.0.0.")]
3252
public static void AddOrUpdate(
@@ -80,7 +100,7 @@ public static void AddOrUpdate(
80100
var job = Job.Create(methodCall);
81101
var id = GetRecurringJobId(job);
82102

83-
Instance.Value.AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
103+
ManagerFactory().AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
84104
}
85105

86106
[Obsolete("Please use an overload with the explicit recurringJobId parameter instead. Will be removed in 2.0.0.")]
@@ -92,7 +112,7 @@ public static void AddOrUpdate(
92112
var job = Job.Create(methodCall);
93113
var id = GetRecurringJobId(job);
94114

95-
Instance.Value.AddOrUpdate(id, job, cronExpression, options);
115+
ManagerFactory().AddOrUpdate(id, job, cronExpression, options);
96116
}
97117

98118
[Obsolete("Please use an overload with the explicit recurringJobId parameter and RecurringJobOptions instead. Will be removed in 2.0.0.")]
@@ -105,7 +125,7 @@ public static void AddOrUpdate<T>(
105125
var job = Job.Create(methodCall);
106126
var id = GetRecurringJobId(job);
107127

108-
Instance.Value.AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
128+
ManagerFactory().AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
109129
}
110130

111131
[Obsolete("Please use an overload with the explicit recurringJobId parameter instead. Will be removed in 2.0.0.")]
@@ -117,7 +137,7 @@ public static void AddOrUpdate<T>(
117137
var job = Job.Create(methodCall);
118138
var id = GetRecurringJobId(job);
119139

120-
Instance.Value.AddOrUpdate(id, job, cronExpression, options);
140+
ManagerFactory().AddOrUpdate(id, job, cronExpression, options);
121141
}
122142

123143
[Obsolete("Please use AddOrUpdate(string, Expression<Action>, Func<string>, RecurringJobOptions) instead. Will be removed in 2.0.0.")]
@@ -229,7 +249,7 @@ public static void AddOrUpdate(
229249
[NotNull] string queue = EnqueuedState.DefaultQueue)
230250
{
231251
var job = Job.Create(methodCall);
232-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
252+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
233253
}
234254

235255
public static void AddOrUpdate(
@@ -247,7 +267,7 @@ public static void AddOrUpdate(
247267
[NotNull] RecurringJobOptions options)
248268
{
249269
var job = Job.Create(methodCall);
250-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
270+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
251271
}
252272

253273
public static void AddOrUpdate(
@@ -269,7 +289,7 @@ public static void AddOrUpdate(
269289
if (queue == null) throw new ArgumentNullException(nameof(queue));
270290

271291
var job = Job.Create(methodCall, queue);
272-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
292+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
273293
}
274294

275295
[Obsolete("Please use AddOrUpdate<T>(string, Expression<Action<T>>, string, RecurringJobOptions) instead. Will be removed in 2.0.0.")]
@@ -281,7 +301,7 @@ public static void AddOrUpdate<T>(
281301
[NotNull] string queue = EnqueuedState.DefaultQueue)
282302
{
283303
var job = Job.Create(methodCall);
284-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
304+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
285305
}
286306

287307
public static void AddOrUpdate<T>(
@@ -299,7 +319,7 @@ public static void AddOrUpdate<T>(
299319
[NotNull] RecurringJobOptions options)
300320
{
301321
var job = Job.Create(methodCall);
302-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
322+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
303323
}
304324

305325
public static void AddOrUpdate<T>(
@@ -321,7 +341,7 @@ public static void AddOrUpdate<T>(
321341
if (queue == null) throw new ArgumentNullException(nameof(queue));
322342

323343
var job = Job.Create(methodCall, queue);
324-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
344+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
325345
}
326346

327347
[Obsolete("Please use an overload with the explicit recurringJobId parameter and RecurringJobOptions instead. Will be removed in 2.0.0.")]
@@ -376,7 +396,7 @@ public static void AddOrUpdate(
376396
var job = Job.Create(methodCall);
377397
var id = GetRecurringJobId(job);
378398

379-
Instance.Value.AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
399+
ManagerFactory().AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
380400
}
381401

382402
[Obsolete("Please use an overload with the explicit recurringJobId parameter instead. Will be removed in 2.0.0.")]
@@ -388,7 +408,7 @@ public static void AddOrUpdate(
388408
var job = Job.Create(methodCall);
389409
var id = GetRecurringJobId(job);
390410

391-
Instance.Value.AddOrUpdate(id, job, cronExpression, options);
411+
ManagerFactory().AddOrUpdate(id, job, cronExpression, options);
392412
}
393413

394414
[Obsolete("Please use an overload with the explicit recurringJobId parameter and RecurringJobOptions instead. Will be removed in 2.0.0.")]
@@ -401,7 +421,7 @@ public static void AddOrUpdate<T>(
401421
var job = Job.FromExpression(methodCall);
402422
var id = GetRecurringJobId(job);
403423

404-
Instance.Value.AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
424+
ManagerFactory().AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
405425
}
406426

407427
[Obsolete("Please use an overload with the explicit recurringJobId parameter instead. Will be removed in 2.0.0.")]
@@ -413,7 +433,7 @@ public static void AddOrUpdate<T>(
413433
var job = Job.FromExpression(methodCall);
414434
var id = GetRecurringJobId(job);
415435

416-
Instance.Value.AddOrUpdate(id, job, cronExpression, options);
436+
ManagerFactory().AddOrUpdate(id, job, cronExpression, options);
417437
}
418438

419439
[Obsolete("Please use AddOrUpdate(string, Expression<Func<Task>>, Func<string>, RecurringJobOptions) instead. Will be removed in 2.0.0.")]
@@ -525,7 +545,7 @@ public static void AddOrUpdate(
525545
[NotNull] string queue = EnqueuedState.DefaultQueue)
526546
{
527547
var job = Job.Create(methodCall);
528-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
548+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
529549
}
530550

531551
public static void AddOrUpdate(
@@ -543,7 +563,7 @@ public static void AddOrUpdate(
543563
[NotNull] RecurringJobOptions options)
544564
{
545565
var job = Job.Create(methodCall);
546-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
566+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
547567
}
548568

549569
public static void AddOrUpdate(
@@ -565,7 +585,7 @@ public static void AddOrUpdate(
565585
if (queue == null) throw new ArgumentNullException(nameof(queue));
566586

567587
var job = Job.Create(methodCall, queue);
568-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
588+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
569589
}
570590

571591
[Obsolete("Please use AddOrUpdate<T>(string, Expression<Func<T, Task>>, string, RecurringJobOptions) instead. Will be removed in 2.0.0.")]
@@ -577,7 +597,7 @@ public static void AddOrUpdate<T>(
577597
[NotNull] string queue = EnqueuedState.DefaultQueue)
578598
{
579599
var job = Job.FromExpression(methodCall);
580-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
600+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue);
581601
}
582602

583603
public static void AddOrUpdate<T>(
@@ -595,7 +615,7 @@ public static void AddOrUpdate<T>(
595615
[NotNull] RecurringJobOptions options)
596616
{
597617
var job = Job.Create(methodCall);
598-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
618+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
599619
}
600620

601621
public static void AddOrUpdate<T>(
@@ -617,24 +637,24 @@ public static void AddOrUpdate<T>(
617637
if (queue == null) throw new ArgumentNullException(nameof(queue));
618638

619639
var job = Job.Create(methodCall, queue);
620-
Instance.Value.AddOrUpdate(recurringJobId, job, cronExpression, options);
640+
ManagerFactory().AddOrUpdate(recurringJobId, job, cronExpression, options);
621641
}
622642

623643
public static void RemoveIfExists([NotNull] string recurringJobId)
624644
{
625-
Instance.Value.RemoveIfExists(recurringJobId);
645+
ManagerFactory().RemoveIfExists(recurringJobId);
626646
}
627647

628648
[Obsolete("Please use the TriggerJob method instead. Will be removed in 2.0.0.")]
629649
public static void Trigger([NotNull] string recurringJobId)
630650
{
631-
Instance.Value.Trigger(recurringJobId);
651+
ManagerFactory().Trigger(recurringJobId);
632652
}
633653

634654
[CanBeNull]
635655
public static string? TriggerJob([NotNull] string recurringJobId)
636656
{
637-
return Instance.Value.TriggerJob(recurringJobId);
657+
return ManagerFactory().TriggerJob(recurringJobId);
638658
}
639659

640660
private static string GetRecurringJobId(Job job)

src/Hangfire.Core/Server/RecurringJobScheduler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ private void ScheduleRecurringJob(BackgroundProcessContext context, IStorageConn
378378

379379
private void RetryRecurringJob(string recurringJobId, RecurringJobEntity recurringJob, DateTime now, Exception error, ILog logger)
380380
{
381-
var errorString = error.ToStringWithOriginalStackTrace(States.FailedState.MaxLinesInExceptionDetails);
381+
var errorString = error.ToStringWithOriginalStackTrace(States.FailedState.MaxLinesInExceptionDetails, includeFileInfo: false);
382382

383383
if (recurringJob.RetryAttempt < MaxRetryAttemptCount)
384384
{

src/Hangfire.Core/States/FailedState.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ public FailedState([NotNull] Exception exception, [CanBeNull] string? serverId)
110110
[NotNull]
111111
public Exception Exception { get; }
112112

113+
[JsonIgnore]
114+
public bool IncludeFileInfo { get; set; } = true;
115+
113116
/// <summary>
114117
/// Gets the server identifier on which the exception occurred.
115118
/// </summary>
@@ -196,7 +199,7 @@ public Dictionary<string, string> SerializeData()
196199
{ "FailedAt", JobHelper.SerializeDateTime(FailedAt) },
197200
{ "ExceptionType", Exception.GetType().FullName! },
198201
{ "ExceptionMessage", Exception.Message },
199-
{ "ExceptionDetails", Exception.ToStringWithOriginalStackTrace(MaxLinesInStackTrace) }
202+
{ "ExceptionDetails", Exception.ToStringWithOriginalStackTrace(MaxLinesInStackTrace, IncludeFileInfo) }
200203
};
201204

202205
if (ServerId != null)

0 commit comments

Comments
 (0)