Skip to content

Commit 414c182

Browse files
authored
Merge branch 'main' into copilot/add-roslyn-analyzer-function-check
2 parents ddea7ad + c45f013 commit 414c182

31 files changed

+572
-232
lines changed

Directory.Build.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
<ImplicitUsings>enable</ImplicitUsings>
88
</PropertyGroup>
99

10+
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
11+
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
12+
<CheckEolTargetFramework>false</CheckEolTargetFramework>
13+
</PropertyGroup>
14+
1015
<!-- Assembly name and namespace -->
1116
<PropertyGroup Condition="!$(MSBuildProjectName.StartsWith('Microsoft.DurableTask'))">
1217
<TopLevelNamespace Condition="'$(TopLevelNamespace)' == ''">Microsoft.DurableTask</TopLevelNamespace>

Directory.Packages.props

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@
99

1010
<!-- Microsoft.Extensions.* Packages -->
1111
<ItemGroup>
12-
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
13-
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
14-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
15-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
16-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
17-
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
18-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
19-
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
20-
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" />
12+
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
13+
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.0" />
14+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
15+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
16+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
17+
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
18+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
19+
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.0" />
20+
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="10.0.0" />
2121
</ItemGroup>
2222

2323
<!-- Azure.* Packages -->
2424
<ItemGroup>
2525
<PackageVersion Include="Azure.Identity" Version="1.17.1" />
2626
<PackageVersion Include="Azure.Storage.Blobs" Version="12.26.0" />
27-
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="2.2.0" />
27+
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="2.51.0" />
2828
</ItemGroup>
2929

3030
<!-- DurableTask Packages -->
3131
<ItemGroup>
3232
<PackageVersion Include="Microsoft.Azure.DurableTask.Core" Version="3.6.0" />
33-
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.2.2" />
33+
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.10.0" />
3434
</ItemGroup>
3535

3636
<!-- Grpc / Protobuf Packages -->
@@ -80,10 +80,10 @@
8080
<PackageVersion Include="DotNext" Version="4.13.1" Condition="'$(TargetFramework)' != 'net8.0' AND '$(TargetFramework)' != 'net10.0'" />
8181
<PackageVersion Include="DotNext" Version="5.19.0" Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net10.0'" />
8282
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
83-
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
83+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.0" />
8484
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
85-
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
85+
<PackageVersion Include="System.Text.Json" Version="10.0.0" />
8686
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" />
8787
</ItemGroup>
8888

89-
</Project>
89+
</Project>

samples/AzureFunctionsUnitTests/SampleUnitTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ public TestResponse(FunctionContext functionContext) : base(functionContext)
200200
public class TestLogger : ILogger
201201
{
202202
// list of all logs emitted, for validation
203-
public IList<string> CapturedLogs {get; set;} = new List<string>();
203+
public IList<string> CapturedLogs { get; set; } = new List<string>();
204204

205-
public IDisposable BeginScope<TState>(TState state) => Mock.Of<IDisposable>();
205+
public IDisposable BeginScope<TState>(TState state) where TState : notnull => Mock.Of<IDisposable>();
206206

207207
public bool IsEnabled(LogLevel logLevel)
208208
{

samples/LargePayloadConsoleApp/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
// Keep threshold small to force externalization for demo purposes
2828
opts.ExternalizeThresholdBytes = 1024; // 1KB
2929
opts.ConnectionString = builder.Configuration.GetValue<string>("DURABLETASK_STORAGE") ?? "UseDevelopmentStorage=true";
30-
opts.ContainerName = builder.Configuration.GetValue<string>("DURABLETASK_PAYLOAD_CONTAINER");
30+
opts.ContainerName = builder.Configuration.GetValue<string>("DURABLETASK_PAYLOAD_CONTAINER") ?? "payloads";
3131
});
3232

3333
// 2) Configure Durable Task client

src/Abstractions/DurableTaskAttribute.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ namespace Microsoft.DurableTask;
88
/// </summary>
99
/// <remarks>
1010
/// This attribute is meant to be used on class definitions that derive from
11-
/// <see cref="TaskOrchestrator{TInput, TOutput}"/> or <see cref="TaskActivity{TInput, TOutput}"/>.
11+
/// <see cref="TaskOrchestrator{TInput, TOutput}"/>, <see cref="TaskActivity{TInput, TOutput}"/>,
12+
/// or TaskEntity{TState} from the Microsoft.DurableTask.Entities namespace.
1213
/// It is used specifically by build-time source generators to generate type-safe methods for invoking
13-
/// orchestrations or activities.
14+
/// orchestrations, activities, or registering entities.
1415
/// </remarks>
1516
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
1617
public sealed class DurableTaskAttribute : Attribute

src/Client/Grpc/GrpcDurableTaskClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public override async Task<string> ScheduleNewOrchestrationInstanceAsync(
110110

111111
DateTimeOffset? startAt = options?.StartAt;
112112
this.logger.SchedulingOrchestration(
113-
request.InstanceId,
113+
request.InstanceId ?? string.Empty,
114114
orchestratorName,
115115
sizeInBytes: request.Input != null ? Encoding.UTF8.GetByteCount(request.Input) : 0,
116116
startAt.GetValueOrDefault(DateTimeOffset.UtcNow));

src/Extensions/AzureBlobPayloads/Options/LargePayloadStorageOptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public LargePayloadStorageOptions(Uri accountUri, TokenCredential credential)
6363
/// Gets or sets the threshold in bytes at which payloads are externalized. Default is 900_000 bytes.
6464
/// Value must not exceed 1 MiB (1,048,576 bytes).
6565
/// </summary>
66-
6766
public int ExternalizeThresholdBytes
6867
{
6968
get => this.externalizeThresholdBytes;

src/Extensions/AzureBlobPayloads/PayloadStore/BlobPayloadStore.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public override async Task<string> UploadAsync(string payLoad, CancellationToken
8989
// using MemoryStream payloadStream = new(payloadBuffer, writable: false);
9090

9191
// await payloadStream.CopyToAsync(compressedBlobStream, bufferSize: DefaultCopyBufferSize, cancellationToken);
92-
await compressedBlobStream.WriteAsync(payloadBuffer, 0, payloadBuffer.Length, cancellationToken);
92+
await WritePayloadAsync(payloadBuffer, compressedBlobStream, cancellationToken);
9393
await compressedBlobStream.FlushAsync(cancellationToken);
9494
await blobStream.FlushAsync(cancellationToken);
9595
}
@@ -99,7 +99,7 @@ public override async Task<string> UploadAsync(string payLoad, CancellationToken
9999

100100
// using MemoryStream payloadStream = new(payloadBuffer, writable: false);
101101
// await payloadStream.CopyToAsync(blobStream, bufferSize: DefaultCopyBufferSize, cancellationToken);
102-
await blobStream.WriteAsync(payloadBuffer, 0, payloadBuffer.Length, cancellationToken);
102+
await WritePayloadAsync(payloadBuffer, blobStream, cancellationToken);
103103
await blobStream.FlushAsync(cancellationToken);
104104
}
105105

@@ -126,11 +126,11 @@ public override async Task<string> DownloadAsync(string token, CancellationToken
126126
{
127127
using GZipStream decompressed = new(contentStream, CompressionMode.Decompress);
128128
using StreamReader reader = new(decompressed, Encoding.UTF8);
129-
return await reader.ReadToEndAsync();
129+
return await ReadToEndAsync(reader, cancellationToken);
130130
}
131131

132132
using StreamReader uncompressedReader = new(contentStream, Encoding.UTF8);
133-
return await uncompressedReader.ReadToEndAsync();
133+
return await ReadToEndAsync(uncompressedReader, cancellationToken);
134134
}
135135

136136
/// <inheritdoc/>
@@ -144,6 +144,27 @@ public override bool IsKnownPayloadToken(string value)
144144
return value.StartsWith(TokenPrefix, StringComparison.Ordinal);
145145
}
146146

147+
static async Task WritePayloadAsync(byte[] payloadBuffer, Stream target, CancellationToken cancellationToken)
148+
{
149+
#if NETSTANDARD2_0
150+
await target.WriteAsync(payloadBuffer, 0, payloadBuffer.Length, cancellationToken).ConfigureAwait(false);
151+
#else
152+
await target.WriteAsync(payloadBuffer.AsMemory(0, payloadBuffer.Length), cancellationToken).ConfigureAwait(false);
153+
#endif
154+
}
155+
156+
static async Task<string> ReadToEndAsync(StreamReader reader, CancellationToken cancellationToken)
157+
{
158+
#if NETSTANDARD2_0
159+
cancellationToken.ThrowIfCancellationRequested();
160+
return await reader.ReadToEndAsync().ConfigureAwait(false);
161+
#elif NET8_0_OR_GREATER
162+
return await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
163+
#else
164+
return await reader.ReadToEndAsync().WaitAsync(cancellationToken).ConfigureAwait(false);
165+
#endif
166+
}
167+
147168
static string EncodeToken(string container, string name) => $"blob:v1:{container}:{name}";
148169

149170
static (string Container, string Name) DecodeToken(string token)

src/Generators/AzureFunctions/DurableFunction.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ public enum DurableFunctionKind
1010
{
1111
Unknown,
1212
Orchestration,
13-
Activity
13+
Activity,
14+
Entity
1415
}
1516

1617
public class DurableFunction

src/Generators/AzureFunctions/SyntaxNodeUtility.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ public static bool TryGetFunctionKind(MethodDeclarationSyntax method, out Durabl
6161
kind = DurableFunctionKind.Activity;
6262
return true;
6363
}
64+
65+
if (attribute.ToString().Equals("EntityTrigger", StringComparison.Ordinal))
66+
{
67+
kind = DurableFunctionKind.Entity;
68+
return true;
69+
}
6470
}
6571
}
6672

@@ -125,7 +131,8 @@ public static bool TryGetParameter(
125131
{
126132
string attributeName = attribute.Name.ToString();
127133
if ((kind == DurableFunctionKind.Activity && attributeName == "ActivityTrigger") ||
128-
(kind == DurableFunctionKind.Orchestration && attributeName == "OrchestratorTrigger"))
134+
(kind == DurableFunctionKind.Orchestration && attributeName == "OrchestratorTrigger") ||
135+
(kind == DurableFunctionKind.Entity && attributeName == "EntityTrigger"))
129136
{
130137
TypeInfo info = model.GetTypeInfo(methodParam.Type);
131138
if (info.Type is INamedTypeSymbol named)

0 commit comments

Comments
 (0)