Skip to content

Commit aed1428

Browse files
authored
Merge branch 'main' into copilot/make-initializestate-async
2 parents 35a13ad + e0ee326 commit aed1428

27 files changed

+1413
-37
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
# Changelog
22

3+
## v1.18.2
4+
- Add copy constructors to TaskOptions and sub-classes by halspang ([#587](https://github.com/microsoft/durabletask-dotnet/pull/587))
5+
- Change FunctionNotFound analyzer severity to Info for cross-assembly scenarios by Copilot ([#584](https://github.com/microsoft/durabletask-dotnet/pull/584))
6+
- Add Roslyn analyzer for non-contextual logger usage in orchestrations (DURABLE0010) by Copilot ([#553](https://github.com/microsoft/durabletask-dotnet/pull/553))
7+
- Add specific logging categories for Worker.Grpc and orchestration logs with backward-compatible opt-in by Copilot ([#583](https://github.com/microsoft/durabletask-dotnet/pull/583))
8+
- Fix flaky integration test race condition in dedup status check by Copilot ([#579](https://github.com/microsoft/durabletask-dotnet/pull/579))
9+
- Add analyzer to suggest input parameter binding over GetInput() by Copilot ([#550](https://github.com/microsoft/durabletask-dotnet/pull/550))
10+
- Add strongly-typed external events with DurableEventAttribute by Copilot ([#549](https://github.com/microsoft/durabletask-dotnet/pull/549))
11+
- Fix orchestration analyzer to detect non-function orchestrations correctly by Copilot ([#572](https://github.com/microsoft/durabletask-dotnet/pull/572))
12+
- Fix race condition in WaitForInstanceAsync causing intermittent test failures by Copilot ([#574](https://github.com/microsoft/durabletask-dotnet/pull/574))
13+
- Add HelpLinkUri to Roslyn analyzer diagnostics by Copilot ([#548](https://github.com/microsoft/durabletask-dotnet/pull/548))
14+
- Add DateTimeOffset.Now and DateTimeOffset.UtcNow detection to Roslyn analyzer by Copilot ([#547](https://github.com/microsoft/durabletask-dotnet/pull/547))
15+
- Bump Google.Protobuf from 3.33.1 to 3.33.2 by dependabot[bot] ([#569](https://github.com/microsoft/durabletask-dotnet/pull/569))
16+
- Add integration test coverage for Suspend/Resume operations by Copilot ([#546](https://github.com/microsoft/durabletask-dotnet/pull/546))
17+
- Bump coverlet.collector from 6.0.2 to 6.0.4 by dependabot[bot] ([#527](https://github.com/microsoft/durabletask-dotnet/pull/527))
18+
- Bump FluentAssertions from 6.12.1 to 6.12.2 by dependabot[bot] ([#528](https://github.com/microsoft/durabletask-dotnet/pull/528))
19+
- Add Azure Functions smoke tests with Docker CI automation by Copilot ([#545](https://github.com/microsoft/durabletask-dotnet/pull/545))
20+
- Bump dotnet-sdk from 10.0.100 to 10.0.101 by dependabot[bot] ([#568](https://github.com/microsoft/durabletask-dotnet/pull/568))
21+
- Add scheduled auto-closure for stale "Needs Author Feedback" issues by Copilot ([#566](https://github.com/microsoft/durabletask-dotnet/pull/566))
22+
323
## v1.18.1
424
- Support dedup status when starting orchestration by wangbill ([#542](https://github.com/microsoft/durabletask-dotnet/pull/542))
525
- Add 404 exception handling in blobpayloadstore.downloadasync by Copilot ([#534](https://github.com/microsoft/durabletask-dotnet/pull/534))

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<!-- DurableTask Packages -->
3333
<ItemGroup>
3434
<PackageVersion Include="Microsoft.Azure.DurableTask.Core" Version="3.6.0" />
35-
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.10.0" />
35+
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.12.1" />
3636
</ItemGroup>
3737

3838
<!-- Grpc / Protobuf Packages -->

eng/targets/Release.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</PropertyGroup>
1818

1919
<PropertyGroup>
20-
<VersionPrefix>1.18.1</VersionPrefix>
20+
<VersionPrefix>1.18.2</VersionPrefix>
2121
<VersionSuffix></VersionSuffix>
2222
</PropertyGroup>
2323

src/Abstractions/TaskOptions.cs

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ public TaskOptions(TaskRetryOptions? retry = null, IDictionary<string, string>?
3030
this.Tags = tags;
3131
}
3232

33+
/// <summary>
34+
/// Initializes a new instance of the <see cref="TaskOptions"/> class by copying from another instance.
35+
/// </summary>
36+
/// <param name="options">The task options to copy from.</param>
37+
public TaskOptions(TaskOptions options)
38+
{
39+
Check.NotNull(options);
40+
this.Retry = options.Retry;
41+
this.Tags = options.Tags;
42+
}
43+
3344
/// <summary>
3445
/// Gets the task retry options.
3546
/// </summary>
@@ -96,12 +107,29 @@ public SubOrchestrationOptions(TaskOptions options, string? instanceId = null)
96107
: base(options)
97108
{
98109
this.InstanceId = instanceId;
99-
if (instanceId is null && options is SubOrchestrationOptions derived)
110+
if (options is SubOrchestrationOptions derived)
100111
{
101-
this.InstanceId = derived.InstanceId;
112+
if (instanceId is null)
113+
{
114+
this.InstanceId = derived.InstanceId;
115+
}
116+
117+
this.Version = derived.Version;
102118
}
103119
}
104120

121+
/// <summary>
122+
/// Initializes a new instance of the <see cref="SubOrchestrationOptions"/> class by copying from another instance.
123+
/// </summary>
124+
/// <param name="options">The sub-orchestration options to copy from.</param>
125+
public SubOrchestrationOptions(SubOrchestrationOptions options)
126+
: base(options)
127+
{
128+
Check.NotNull(options);
129+
this.InstanceId = options.InstanceId;
130+
this.Version = options.Version;
131+
}
132+
105133
/// <summary>
106134
/// Gets the orchestration instance ID.
107135
/// </summary>
@@ -116,15 +144,51 @@ public SubOrchestrationOptions(TaskOptions options, string? instanceId = null)
116144
/// <summary>
117145
/// Options for submitting new orchestrations via the client.
118146
/// </summary>
119-
/// <param name="InstanceId">
120-
/// The unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used.
121-
/// </param>
122-
/// <param name="StartAt">
123-
/// The time when the orchestration instance should start executing. If not specified or if a date-time in the past
124-
/// is specified, the orchestration instance will be scheduled immediately.
125-
/// </param>
126-
public record StartOrchestrationOptions(string? InstanceId = null, DateTimeOffset? StartAt = null)
147+
public record StartOrchestrationOptions
127148
{
149+
/// <summary>
150+
/// Initializes a new instance of the <see cref="StartOrchestrationOptions"/> class.
151+
/// </summary>
152+
/// <param name="InstanceId">
153+
/// The unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used.
154+
/// </param>
155+
/// <param name="StartAt">
156+
/// The time when the orchestration instance should start executing. If not specified or if a date-time in the past
157+
/// is specified, the orchestration instance will be scheduled immediately.
158+
/// </param>
159+
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter - using PascalCase to maintain backward compatibility with positional record syntax
160+
public StartOrchestrationOptions(string? InstanceId = null, DateTimeOffset? StartAt = null)
161+
#pragma warning restore SA1313
162+
{
163+
this.InstanceId = InstanceId;
164+
this.StartAt = StartAt;
165+
}
166+
167+
/// <summary>
168+
/// Initializes a new instance of the <see cref="StartOrchestrationOptions"/> class by copying from another instance.
169+
/// </summary>
170+
/// <param name="options">The start orchestration options to copy from.</param>
171+
public StartOrchestrationOptions(StartOrchestrationOptions options)
172+
{
173+
Check.NotNull(options);
174+
this.InstanceId = options.InstanceId;
175+
this.StartAt = options.StartAt;
176+
this.Tags = options.Tags;
177+
this.Version = options.Version;
178+
this.DedupeStatuses = options.DedupeStatuses;
179+
}
180+
181+
/// <summary>
182+
/// Gets the unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used.
183+
/// </summary>
184+
public string? InstanceId { get; init; }
185+
186+
/// <summary>
187+
/// Gets the time when the orchestration instance should start executing. If not specified or if a date-time in the past
188+
/// is specified, the orchestration instance will be scheduled immediately.
189+
/// </summary>
190+
public DateTimeOffset? StartAt { get; init; }
191+
128192
/// <summary>
129193
/// Gets the tags to associate with the orchestration instance.
130194
/// </summary>

src/Abstractions/TaskOrchestrationContext.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,28 @@ public virtual Task CreateTimer(TimeSpan delay, CancellationToken cancellationTo
222222
/// </param>
223223
/// <param name="timeout">The amount of time to wait before cancelling the external event task.</param>
224224
/// <inheritdoc cref="WaitForExternalEvent(string, CancellationToken)"/>
225-
public async Task<T> WaitForExternalEvent<T>(string eventName, TimeSpan timeout)
225+
public Task<T> WaitForExternalEvent<T>(string eventName, TimeSpan timeout)
226+
{
227+
return this.WaitForExternalEvent<T>(eventName, timeout, CancellationToken.None);
228+
}
229+
230+
/// <param name="eventName">
231+
/// The name of the event to wait for. Event names are case-insensitive. External event names can be reused any
232+
/// number of times; they are not required to be unique.
233+
/// </param>
234+
/// <param name="timeout">The amount of time to wait before cancelling the external event task.</param>
235+
/// <param name="cancellationToken">A <c>CancellationToken</c> to use to abort waiting for the event.</param>
236+
/// <inheritdoc cref="WaitForExternalEvent(string, CancellationToken)"/>
237+
public async Task<T> WaitForExternalEvent<T>(string eventName, TimeSpan timeout, CancellationToken cancellationToken)
226238
{
227239
// Timeouts are implemented using durable timers.
228240
using CancellationTokenSource timerCts = new();
229241
Task timeoutTask = this.CreateTimer(timeout, timerCts.Token);
230242

231-
using CancellationTokenSource eventCts = new();
243+
// Create a linked cancellation token source from the external cancellation token.
244+
// This allows us to cancel the event wait either when the external token is cancelled
245+
// or when the timeout fires (by calling eventCts.Cancel()).
246+
using CancellationTokenSource eventCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
232247
Task<T> externalEventTask = this.WaitForExternalEvent<T>(eventName, eventCts.Token);
233248

234249
// Wait for either task to complete and then cancel the one that didn't.

src/Analyzers/Activities/FunctionNotFoundAnalyzer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public sealed class FunctionNotFoundAnalyzer : DiagnosticAnalyzer
3737
ActivityNotFoundTitle,
3838
ActivityNotFoundMessageFormat,
3939
AnalyzersCategories.Activity,
40-
DiagnosticSeverity.Warning,
40+
DiagnosticSeverity.Info,
4141
customTags: [WellKnownDiagnosticTags.CompilationEnd],
4242
isEnabledByDefault: true,
4343
helpLinkUri: "https://go.microsoft.com/fwlink/?linkid=2346202");
@@ -47,7 +47,7 @@ public sealed class FunctionNotFoundAnalyzer : DiagnosticAnalyzer
4747
SubOrchestrationNotFoundTitle,
4848
SubOrchestrationNotFoundMessageFormat,
4949
AnalyzersCategories.Orchestration,
50-
DiagnosticSeverity.Warning,
50+
DiagnosticSeverity.Info,
5151
customTags: [WellKnownDiagnosticTags.CompilationEnd],
5252
isEnabledByDefault: true,
5353
helpLinkUri: "https://go.microsoft.com/fwlink/?linkid=2346202");

src/Analyzers/AnalyzerReleases.Shipped.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
Rule ID | Category | Severity | Notes
99
--------|----------|----------|-------
10-
DURABLE2003 | Activity | Warning | **FunctionNotFoundAnalyzer**: Warns when an activity function call references a name that does not match any defined activity in the compilation.
11-
DURABLE2004 | Orchestration | Warning | **FunctionNotFoundAnalyzer**: Warns when a sub-orchestration call references a name that does not match any defined orchestrator in the compilation.
10+
DURABLE2003 | Activity | Info | **FunctionNotFoundAnalyzer**: Reports when an activity function call references a name that does not match any defined activity in the compilation. If the function is defined in another assembly, this diagnostic can be safely ignored. Static resolution across referenced assemblies is not supported.
11+
DURABLE2004 | Orchestration | Info | **FunctionNotFoundAnalyzer**: Reports when a sub-orchestration call references a name that does not match any defined orchestrator in the compilation. If the function is defined in another assembly, this diagnostic can be safely ignored. Static resolution across referenced assemblies is not supported.
1212

1313
## Release 0.1.0
1414

src/Analyzers/AnalyzerReleases.Unshipped.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
Rule ID | Category | Severity | Notes
77
--------|----------|----------|-------
88
DURABLE0009 | Orchestration | Info | **GetInputOrchestrationAnalyzer**: Suggests using input parameter binding instead of ctx.GetInput<T>() in orchestration methods.
9+
DURABLE0010 | Orchestration | Warning | **LoggerOrchestrationAnalyzer**: Warns when a non-contextual ILogger is used in an orchestration method. Orchestrations should use `context.CreateReplaySafeLogger()` instead of injecting ILogger directly.

src/Analyzers/Analyzers.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</PropertyGroup>
1212

1313
<PropertyGroup>
14-
<VersionPrefix>0.2.0</VersionPrefix>
14+
<VersionPrefix>0.3.0</VersionPrefix>
1515
<VersionSuffix></VersionSuffix>
1616
<PackageDescription>.NET Analyzers for the Durable Task SDK.</PackageDescription>
1717
<NeutralLanguage>en</NeutralLanguage>

src/Analyzers/KnownTypeSymbols.Net.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public sealed partial class KnownTypeSymbols
2323
INamedTypeSymbol? cancellationToken;
2424
INamedTypeSymbol? environment;
2525
INamedTypeSymbol? httpClient;
26+
INamedTypeSymbol? iLogger;
2627

2728
/// <summary>
2829
/// Gets a Guid type symbol.
@@ -75,4 +76,9 @@ public sealed partial class KnownTypeSymbols
7576
/// Gets an HttpClient type symbol.
7677
/// </summary>
7778
public INamedTypeSymbol? HttpClient => this.GetOrResolveFullyQualifiedType(typeof(HttpClient).FullName, ref this.httpClient);
79+
80+
/// <summary>
81+
/// Gets an ILogger type symbol.
82+
/// </summary>
83+
public INamedTypeSymbol? ILogger => this.GetOrResolveFullyQualifiedType("Microsoft.Extensions.Logging.ILogger", ref this.iLogger);
7884
}

0 commit comments

Comments
 (0)