Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"Bash(dotnet test:*)",
"Bash(dotnet build:*)",
"Bash(ls:*)",
"Bash(dotnet publish:*)"
"Bash(dotnet publish:*)",
"Bash(dotnet clean:*)",
"Bash(dotnet restore:*)"
]
}
}
29 changes: 24 additions & 5 deletions src/MinimalWorker.Generators/WorkerEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,11 @@ private static void EmitWorkerExtension(StringBuilder sb, List<WorkerInvocationM

foreach (var worker in workers)
{
// Build signature from worker parameters - strip global:: prefix and normalize spacing to match runtime format
// Build signature from worker parameters and return type - strip global:: prefix and normalize spacing to match runtime format
// Runtime uses FormatTypeName which joins generic args with "," (no space), so we must do the same
var paramTypes = string.Join(",", worker.Parameters.Select(p => p.Type.Replace("global::", "").Replace(", ", ",")));
var signature = $"{worker.Type}:{paramTypes}";
var returnType = worker.ReturnType.Replace("global::", "").Replace(", ", ",");
var signature = $"{worker.Type}:{paramTypes}:{returnType}";

if (!workerMap.ContainsKey(signature))
{
Expand Down Expand Up @@ -567,12 +568,18 @@ private static void EmitContinuousWorkerInit(StringBuilder sb, WorkerInvocationM
sb.AppendLine(" succeeded = true; // Mark as success to avoid error handling");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue)");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue && timeoutCts?.Token.IsCancellationRequested == true && !token.IsCancellationRequested)");
sb.AppendLine(" {");
sb.AppendLine(" // Timeout - don't retry timeouts");
sb.AppendLine(" lastException = new TimeoutException($\"Worker '{workerName}' execution timed out after {timeout.Value}.\");");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (TimeoutException tex) when (timeout.HasValue)");
sb.AppendLine(" {");
sb.AppendLine(" // User-thrown TimeoutException - don't retry when timeout is configured");
sb.AppendLine(" lastException = tex;");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (Exception ex)");
sb.AppendLine(" {");
sb.AppendLine(" lastException = ex;");
Expand Down Expand Up @@ -703,12 +710,18 @@ private static void EmitPeriodicWorkerInit(StringBuilder sb, WorkerInvocationMod
sb.AppendLine(" succeeded = true; // Mark as success to avoid error handling");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue)");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue && timeoutCts?.Token.IsCancellationRequested == true && !token.IsCancellationRequested)");
sb.AppendLine(" {");
sb.AppendLine(" // Timeout - don't retry timeouts");
sb.AppendLine(" lastException = new TimeoutException($\"Worker '{workerName}' execution timed out after {timeout.Value}.\");");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (TimeoutException tex) when (timeout.HasValue)");
sb.AppendLine(" {");
sb.AppendLine(" // User-thrown TimeoutException - don't retry when timeout is configured");
sb.AppendLine(" lastException = tex;");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (Exception ex)");
sb.AppendLine(" {");
sb.AppendLine(" lastException = ex;");
Expand Down Expand Up @@ -865,12 +878,18 @@ private static void EmitCronWorkerInit(StringBuilder sb, WorkerInvocationModel w
sb.AppendLine(" succeeded = true; // Mark as success to avoid error handling");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue)");
sb.AppendLine(" catch (OperationCanceledException) when (timeout.HasValue && timeoutCts?.Token.IsCancellationRequested == true && !token.IsCancellationRequested)");
sb.AppendLine(" {");
sb.AppendLine(" // Timeout - don't retry timeouts");
sb.AppendLine(" lastException = new TimeoutException($\"Worker '{workerName}' execution timed out after {timeout.Value}.\");");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (TimeoutException tex) when (timeout.HasValue)");
sb.AppendLine(" {");
sb.AppendLine(" // User-thrown TimeoutException - don't retry when timeout is configured");
sb.AppendLine(" lastException = tex;");
sb.AppendLine(" break;");
sb.AppendLine(" }");
sb.AppendLine(" catch (Exception ex)");
sb.AppendLine(" {");
sb.AppendLine(" lastException = ex;");
Expand Down
16 changes: 10 additions & 6 deletions src/MinimalWorker/BackgroundWorkerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ internal static void ClearRegistrations()
private static string FormatTypeName(Type type)
{
// Map common types to their C# keyword equivalents
if (type == typeof(void)) return "void";
if (type == typeof(string)) return "string";
if (type == typeof(int)) return "int";
if (type == typeof(long)) return "long";
Expand Down Expand Up @@ -415,7 +416,8 @@ public static IWorkerBuilder RunBackgroundWorker(this IHost host, Delegate actio
{
var id = System.Threading.Interlocked.Increment(ref _registrationCounter);
var parameters = action.Method.GetParameters();
var signature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var paramSignature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var returnType = FormatTypeName(action.Method.ReturnType);

var registration = new WorkerRegistration
{
Expand All @@ -425,7 +427,7 @@ public static IWorkerBuilder RunBackgroundWorker(this IHost host, Delegate actio
Type = WorkerType.Continuous,
Host = host,
ParameterCount = parameters.Length,
Signature = $"{WorkerType.Continuous}:{signature}",
Signature = $"{WorkerType.Continuous}:{paramSignature}:{returnType}",
OnError = null
};

Expand Down Expand Up @@ -478,7 +480,8 @@ public static IWorkerBuilder RunPeriodicBackgroundWorker(this IHost host, TimeSp

var id = System.Threading.Interlocked.Increment(ref _registrationCounter);
var parameters = action.Method.GetParameters();
var signature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var paramSignature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var returnType = FormatTypeName(action.Method.ReturnType);

var registration = new WorkerRegistration
{
Expand All @@ -489,7 +492,7 @@ public static IWorkerBuilder RunPeriodicBackgroundWorker(this IHost host, TimeSp
Schedule = timespan,
Host = host,
ParameterCount = parameters.Length,
Signature = $"{WorkerType.Periodic}:{signature}",
Signature = $"{WorkerType.Periodic}:{paramSignature}:{returnType}",
OnError = null
};

Expand Down Expand Up @@ -556,7 +559,8 @@ public static IWorkerBuilder RunCronBackgroundWorker(this IHost host, string cro

var id = System.Threading.Interlocked.Increment(ref _registrationCounter);
var parameters = action.Method.GetParameters();
var signature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var paramSignature = string.Join(",", parameters.Select(p => FormatTypeName(p.ParameterType)));
var returnType = FormatTypeName(action.Method.ReturnType);

var registration = new WorkerRegistration
{
Expand All @@ -567,7 +571,7 @@ public static IWorkerBuilder RunCronBackgroundWorker(this IHost host, string cro
Schedule = cronExpression,
Host = host,
ParameterCount = parameters.Length,
Signature = $"{WorkerType.Cron}:{signature}",
Signature = $"{WorkerType.Cron}:{paramSignature}:{returnType}",
OnError = null
};

Expand Down
Loading
Loading