Skip to content

Commit d9d4f0d

Browse files
authored
Remove sidecar dependency and add netcoreapp3.1 TFM (#2157)
* Replaced net60 target with netcoreapp3.1 * Added Functions V2 validation workflows for .NET and Python
1 parent b544ba7 commit d9d4f0d

26 files changed

+1384
-255
lines changed

.github/workflows/smoketest-dotnet-isolated-v4.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Smoke Test - .NET Isolated
1+
name: Smoke Test - .NET Isolated on Functions V4
22

33
on:
44
push:
@@ -19,6 +19,6 @@ jobs:
1919
- uses: actions/checkout@v2
2020

2121
# Validation is blocked on https://github.com/Azure/azure-functions-host/issues/7995
22-
- name: Run .NET Isolated Smoke Test
22+
- name: Run V4 .NET Isolated Smoke Test
2323
run: test/SmokeTests/e2e-test.ps1 -DockerfilePath test/SmokeTests/OOProcSmokeTests/DotNetIsolated/Dockerfile -HttpStartPath api/StartHelloCitiesTyped -NoValidation
2424
shell: pwsh
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Smoke Test - .NET on Functions V2
2+
3+
on:
4+
push:
5+
branches: [ main, dev ]
6+
paths:
7+
- 'src/**'
8+
- 'test/SmokeTests/SmokeTestsV2/**'
9+
pull_request:
10+
branches: [ main, dev ]
11+
paths:
12+
- 'src/**'
13+
- 'test/SmokeTests/SmokeTestsV2/**'
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v2
20+
- name: Run V2 .NET Smoke Test
21+
run: test/SmokeTests/e2e-test.ps1 -DockerfilePath test/SmokeTests/SmokeTestsV2/Dockerfile -HttpStartPath api/HttpStart
22+
shell: pwsh

.github/workflows/smoketest-dotnet-v3.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Smoke Test - .NET V3
1+
name: Smoke Test - .NET on Functions V3
22

33
on:
44
push:
@@ -17,6 +17,6 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@v2
20-
- name: Run .NET V3 Smoke Test
20+
- name: Run V3 .NET Smoke Test
2121
run: test/SmokeTests/e2e-test.ps1 -DockerfilePath test/SmokeTests/SmokeTestsV3/Dockerfile -HttpStartPath api/HttpStart
2222
shell: pwsh

.github/workflows/smoketest-node14-v4.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Smoke Test - Node14 V4
1+
name: Smoke Test - Node 14 on Functions V4
22

33
on:
44
push:
@@ -17,6 +17,6 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@v2
20-
- name: Run Node14 V4 Smoke Test
20+
- name: Run V4 Node 14 Smoke Test
2121
run: test/SmokeTests/e2e-test.ps1 -DockerfilePath test/SmokeTests/OOProcSmokeTests/durableJS/Dockerfile -HttpStartPath api/DurableFunctionsHttpStart
2222
shell: pwsh
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Smoke Test - Python 3.7 on Functions V2
2+
3+
on:
4+
push:
5+
branches: [ main, dev ]
6+
paths:
7+
- 'src/**'
8+
- 'test/SmokeTests/OOProcSmokeTests/durablePy/**'
9+
pull_request:
10+
branches: [ main, dev ]
11+
paths:
12+
- 'src/**'
13+
- 'test/SmokeTests/OOProcSmokeTests/durablePy/**'
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v2
20+
- name: Run V2 Python 3.7 Smoke Test
21+
run: test/SmokeTests/e2e-test.ps1 -DockerfilePath test/SmokeTests/OOProcSmokeTests/durablePy/Dockerfile -HttpStartPath api/DurableFunctionsHttpStart -ContainerName pyApp
22+
shell: pwsh

WebJobs.Extensions.DurableTask.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
2424
azure-pipelines-release.yml = azure-pipelines-release.yml
2525
README.md = README.md
2626
release_notes.md = release_notes.md
27+
.stylecop\stylecop.json = .stylecop\stylecop.json
2728
EndProjectSection
2829
EndProject
2930
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VSSampleV1", "test\SmokeTests\SmokeTestsV1\VSSampleV1.csproj", "{78141F66-4DDD-4ABB-9DE3-D0B426FE8110}"
@@ -38,10 +39,17 @@ EndProject
3839
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VSSampleV3", "test\SmokeTests\SmokeTestsV3\VSSampleV3.csproj", "{F1611EF4-457B-47CB-94E9-B611EE488984}"
3940
EndProject
4041
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "JavaScript", "JavaScript", "{7B2EDAEC-CFD0-404A-8E52-133FFF595C2F}"
42+
ProjectSection(SolutionItems) = preProject
43+
test\SmokeTests\OOProcSmokeTests\durableJS\Dockerfile = test\SmokeTests\OOProcSmokeTests\durableJS\Dockerfile
44+
EndProjectSection
4145
EndProject
4246
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "extensions", "test\SmokeTests\OOProcSmokeTests\durableJS\extensions.csproj", "{9BA6093A-F71A-49F9-A159-B98ACBE41636}"
4347
EndProject
4448
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Python", "Python", "{FA53EBC4-8265-4063-B9F8-0D5EA0366B90}"
49+
ProjectSection(SolutionItems) = preProject
50+
test\SmokeTests\OOProcSmokeTests\durablePy\Dockerfile = test\SmokeTests\OOProcSmokeTests\durablePy\Dockerfile
51+
test\SmokeTests\OOProcSmokeTests\durablePy\requirements.txt = test\SmokeTests\OOProcSmokeTests\durablePy\requirements.txt
52+
EndProjectSection
4553
EndProject
4654
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "extensions", "test\SmokeTests\OOProcSmokeTests\durablePy\extensions.csproj", "{CB481383-8B54-4FCB-8DCB-F348E08C2A9C}"
4755
EndProject
@@ -77,8 +85,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pipelines", "pipelines", "{
7785
ProjectSection(SolutionItems) = preProject
7886
azure-pipelines.yml = azure-pipelines.yml
7987
.github\workflows\smoketest-dotnet-isolated-v4.yml = .github\workflows\smoketest-dotnet-isolated-v4.yml
88+
.github\workflows\smoketest-dotnet-v2.yml = .github\workflows\smoketest-dotnet-v2.yml
8089
.github\workflows\smoketest-dotnet-v3.yml = .github\workflows\smoketest-dotnet-v3.yml
8190
.github\workflows\smoketest-node14-v4.yml = .github\workflows\smoketest-node14-v4.yml
91+
.github\workflows\smoketest-python37-v2.yml = .github\workflows\smoketest-python37-v2.yml
8292
EndProjectSection
8393
EndProject
8494
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DFPerfScenariosV1", "test\DFPerfScenariosV1\DFPerfScenariosV1.csproj", "{65F904AA-0F6F-48CB-BE19-593B7D68152A}"

release_notes.md

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,16 @@
11
## New Features
2-
- Azure Durable Functions now supports identity-based connections. See [here](https://docs.microsoft.com/azure/azure-functions/functions-reference?tabs=blob#connecting-to-host-storage-with-an-identity-preview) for details on how to configure these connections ([#2014](https://github.com/Azure/azure-functions-durable-extension/pull/2014)) - contributed by [@wsugarman](https://github.com/wsugarman)
3-
- `IConnectionStringResolver` has been deprecated in favor of `IConnectionInfoResolver`
4-
- Similarly, both `StandardConnectionStringProvider` and `WebJobsConnectionStringProvider` have been deprecated in favor of `StandardConnectionInfoProvider` and `WebJobsConnectionInfoProvider`
5-
- Initial support for .NET Isolated
6-
- Added support for long timers for Out-of-Proc SDKs
7-
- Updated the Replay Schema version to V3 for Out-of-Proc SDKs
82

9-
## Bug fixes
3+
None
104

11-
All bug fixes are coming in transitively via our DTFx dependency updates:
5+
## Bug fixes
126

13-
- Fix for stuck orchestration issue caused by incorrect de-dupe flagging (https://github.com/Azure/durabletask/pull/708)
14-
- Fix for stuck orchestration issue caused by certain partition movement issues (https://github.com/Azure/durabletask/pull/710)
15-
- Fix for noisy error message in DTFx logs (ArgumentException: A lease ID must be specified when changing a lease) (https://github.com/Azure/durabletask/issues/406)
16-
- Fix some false positives in deadlock detection that resulted in unnecessary ExecutionEngineExceptions (https://github.com/Azure/durabletask/pull/678)
17-
- Fix issue related to in-order delivery guarantees for Durable Entities (https://github.com/Azure/durabletask/pull/680)
18-
- Improved logging for lease/partition management (https://github.com/Azure/durabletask/pull/699)
19-
- Reduce GC impact of lease blob operations (https://github.com/Azure/durabletask/pull/673)
7+
None
208

219
## Breaking Changes
2210

23-
See dependency updates below, which can be breaking if there are hard dependency conflicts (like .NET Framework 4.6.1)
11+
None
2412

2513
## Dependency Updates
2614

27-
- Added .NET 6 target
28-
- Added DurableTask.Sidecar v0.3.0 dependency (.NET 6 only), with transitive dependency on Grpc.AspNetCore.Server v2.38
29-
- Updated minimum C# compiler version to 9.0
30-
- Added [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure/1.1.1) v1.1.1 as a dependency for Azure Functions 2.0 and beyond
31-
- Azure.Identity 1.1.1 -> 1.5.0 for Azure Functions 2.0 and beyond
32-
- Microsoft.Azure.WebJobs 3.0.14 -> 3.0.31 for for Azure Functions 2.0 and beyond
33-
- .NET Framework v4.6.1 -> v4.6.2 to stay within official support window
34-
- [DurableTask.AzureStorage](https://www.nuget.org/packages/Microsoft.Azure.DurableTask.AzureStorage/) 1.10.1 -> 1.11.0
35-
- [DurableTask.Core](https://www.nuget.org/packages/Microsoft.Azure.DurableTask.Core/) 2.7.0 -> 2.9.0
15+
- Removed .NET 6 target and added .NET Core 3.1 target
16+
- Removed DurableTask.Sidecar v0.3.0 dependency

src/WebJobs.Extensions.DurableTask/Bindings/OrchestrationTriggerAttributeBindingProvider.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,21 +141,21 @@ public Task<ITriggerData> BindAsync(object? value, ValueBindingContext context)
141141
var triggerData = new TriggerData(contextValueProvider, bindingData);
142142
return Task.FromResult<ITriggerData>(triggerData);
143143
}
144-
#if NET6_0_OR_GREATER
144+
#if FUNCTIONS_V3_OR_GREATER
145145
else if (value is RemoteOrchestratorContext remoteContext)
146146
{
147147
// Generate a byte array which is the serialized protobuf payload
148148
// https://developers.google.com/protocol-buffers/docs/csharptutorial#parsing_and_serialization
149149
var orchestratorRequest = new Microsoft.DurableTask.Protobuf.OrchestratorRequest()
150150
{
151151
InstanceId = remoteContext.InstanceId,
152-
PastEvents = { remoteContext.PastEvents.Select(Microsoft.DurableTask.Sidecar.Grpc.ProtobufUtils.ToHistoryEventProto) },
153-
NewEvents = { remoteContext.NewEvents.Select(Microsoft.DurableTask.Sidecar.Grpc.ProtobufUtils.ToHistoryEventProto) },
152+
PastEvents = { remoteContext.PastEvents.Select(ProtobufUtils.ToHistoryEventProto) },
153+
NewEvents = { remoteContext.NewEvents.Select(ProtobufUtils.ToHistoryEventProto) },
154154
};
155155

156156
// We convert the binary payload into a base64 string because that seems to be the most commonly supported
157157
// format for Azure Functions language workers. Attempts to send unencoded byte[] payloads were unsuccessful.
158-
string encodedRequest = Microsoft.DurableTask.Sidecar.Grpc.ProtobufUtils.Base64Encode(orchestratorRequest);
158+
string encodedRequest = ProtobufUtils.Base64Encode(orchestratorRequest);
159159
var contextValueProvider = new ObjectValueProvider(encodedRequest, typeof(string));
160160
var triggerData = new TriggerData(contextValueProvider, EmptyBindingData);
161161
return Task.FromResult<ITriggerData>(triggerData);

src/WebJobs.Extensions.DurableTask/DurableTaskExtension.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ public class DurableTaskExtension :
6666
new ConcurrentDictionary<FunctionName, RegisteredFunctionInfo>();
6767

6868
private readonly AsyncLock taskHubLock = new AsyncLock();
69-
#if !FUNCTIONS_V1
69+
#if FUNCTIONS_V2_OR_GREATER
7070
#pragma warning disable CS0169
7171
private readonly ITelemetryActivator telemetryActivator;
7272
#pragma warning restore CS0169
7373
#endif
74-
#if NET6_0_OR_GREATER
74+
#if FUNCTIONS_V3_OR_GREATER
7575
private readonly LocalGrpcListener localGrpcListener;
7676
#endif
7777
private readonly bool isOptionsConfigured;
@@ -104,7 +104,6 @@ public DurableTaskExtension()
104104
}
105105
#endif
106106

107-
#pragma warning disable CS1572 // XML comment has a param tag for 'XXX', but there is no parameter by that name
108107
/// <summary>
109108
/// Initializes a new instance of the <see cref="DurableTaskExtension"/>.
110109
/// </summary>
@@ -132,7 +131,7 @@ public DurableTaskExtension(
132131
#pragma warning disable CS0612 // Type or member is obsolete
133132
IPlatformInformation platformInformationService = null,
134133
#pragma warning restore CS0612 // Type or member is obsolete
135-
#if !FUNCTIONS_V1
134+
#if FUNCTIONS_V2_OR_GREATER
136135
IErrorSerializerSettingsFactory errorSerializerSettingsFactory = null,
137136
#pragma warning disable CS0618 // Type or member is obsolete
138137
IWebHookProvider webhookProvider = null,
@@ -141,7 +140,6 @@ public DurableTaskExtension(
141140
#else
142141
IErrorSerializerSettingsFactory errorSerializerSettingsFactory = null)
143142
#endif
144-
#pragma warning restore CS1572 // XML comment has a param tag for 'XXX', but there is no parameter by that name
145143
{
146144
// Options will be null in Functions v1 runtime - populated later.
147145
this.Options = options?.Value ?? new DurableTaskOptions();
@@ -198,10 +196,9 @@ public DurableTaskExtension(
198196
if (runtimeType == WorkerRuntimeType.DotNetIsolated || runtimeType == WorkerRuntimeType.Java)
199197
{
200198
this.OutOfProcProtocol = OutOfProcOrchestrationProtocol.MiddlewarePassthrough;
201-
#if NET6_0_OR_GREATER
199+
#if FUNCTIONS_V3_OR_GREATER
202200
this.localGrpcListener = new LocalGrpcListener(
203201
this,
204-
this.loggerFactory,
205202
this.defaultDurabilityProvider,
206203
this.defaultDurabilityProvider);
207204
this.HostLifetimeService.OnStopped.Register(this.StopLocalGrpcServer);
@@ -435,11 +432,21 @@ void IExtensionConfigProvider.Initialize(ExtensionConfigContext context)
435432
// Note that the order of the middleware added determines the order in which it executes.
436433
if (this.OutOfProcProtocol == OutOfProcOrchestrationProtocol.MiddlewarePassthrough)
437434
{
435+
#if FUNCTIONS_V3_OR_GREATER
438436
// This is a newer, more performant flavor of orchestration/activity middleware that is being
439437
// enabled for newer language runtimes. Support for entities in this model is TBD.
440438
var ooprocMiddleware = new OutOfProcMiddleware(this);
441439
this.taskHubWorker.AddActivityDispatcherMiddleware(ooprocMiddleware.CallActivityAsync);
442440
this.taskHubWorker.AddOrchestrationDispatcherMiddleware(ooprocMiddleware.CallOrchestratorAsync);
441+
#else
442+
// This can happen if, for example, a Java user tries to use Durable Functions while targeting V2 or V3 extension bundles
443+
// because those bundles target .NET Core 2.2, which doesn't support the gRPC libraries used in the modern out-of-proc implementation.
444+
throw new PlatformNotSupportedException(
445+
"This project type is not supported on this version of the Azure Functions runtime. Please upgrade to Azure Functions V3 or higher. " +
446+
"If you are using a language that supports extension bundles, please use extension bundles V4 or higher. " +
447+
"For more information on Azure Functions versions, see https://docs.microsoft.com/azure/azure-functions/functions-versions. " +
448+
"For more information on extension bundles, see https://docs.microsoft.com/azure/azure-functions/functions-bindings-register#extension-bundles.");
449+
#endif
443450
}
444451
else
445452
{
@@ -450,22 +457,25 @@ void IExtensionConfigProvider.Initialize(ExtensionConfigContext context)
450457
this.taskHubWorker.AddOrchestrationDispatcherMiddleware(this.OrchestrationMiddleware);
451458
}
452459

453-
#if !FUNCTIONS_V1
454460
// The RPC server needs to be started sometime before any functions can be triggered
455461
// and this is the latest point in the pipeline available to us.
456-
this.StartLocalHttpServer();
457-
#endif
458-
#if NET6_0_OR_GREATER
462+
#if FUNCTIONS_V3_OR_GREATER
459463
if (this.OutOfProcProtocol == OutOfProcOrchestrationProtocol.MiddlewarePassthrough)
460464
{
461465
this.StartLocalGrpcServer();
462466
}
467+
#endif
468+
#if FUNCTIONS_V2_OR_GREATER
469+
if (this.OutOfProcProtocol == OutOfProcOrchestrationProtocol.OrchestratorShim)
470+
{
471+
this.StartLocalHttpServer();
472+
}
463473
#endif
464474
}
465475

466476
internal string GetLocalRpcAddress()
467477
{
468-
#if NET6_0_OR_GREATER
478+
#if FUNCTIONS_V3_OR_GREATER
469479
if (this.OutOfProcProtocol == OutOfProcOrchestrationProtocol.MiddlewarePassthrough)
470480
{
471481
return this.localGrpcListener.ListenAddress;
@@ -520,7 +530,7 @@ public void Dispose()
520530
this.eventSourceListener?.Dispose();
521531
}
522532

523-
#if !FUNCTIONS_V1
533+
#if FUNCTIONS_V2_OR_GREATER
524534
private void StartLocalHttpServer()
525535
{
526536
bool? shouldEnable = this.Options.LocalRpcEndpointEnabled;
@@ -557,7 +567,7 @@ private void StopLocalHttpServer()
557567
}
558568
#endif
559569

560-
#if NET6_0_OR_GREATER
570+
#if FUNCTIONS_V3_OR_GREATER
561571
private void StartLocalGrpcServer()
562572
{
563573
this.localGrpcListener.StartAsync().GetAwaiter().GetResult();

src/WebJobs.Extensions.DurableTask/DurableTaskJobHostConfigurationExtensions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using Microsoft.Extensions.Azure;
1313
using Microsoft.Extensions.DependencyInjection;
1414
using Microsoft.Extensions.DependencyInjection.Extensions;
15-
using Microsoft.Extensions.Hosting;
1615
using Microsoft.Extensions.Options;
1716
#else
1817
using Microsoft.Azure.WebJobs.Extensions.DurableTask.ContextImplementations;
@@ -181,5 +180,5 @@ public static void UseDurableTask(
181180
extensions.RegisterExtension<IExtensionConfigProvider>(listenerConfig);
182181
}
183182
#endif
184-
}
185183
}
184+
}

0 commit comments

Comments
 (0)