-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Go SDK dev server and add a couple of .NET update features (#364)
- Loading branch information
Showing
10 changed files
with
272 additions
and
307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
namespace update.activities; | ||
|
||
using Temporalio.Activities; | ||
using Temporalio.Client; | ||
using Temporalio.Features.Harness; | ||
using Temporalio.Worker; | ||
using Temporalio.Workflows; | ||
using Xunit; | ||
|
||
class Feature : IFeature | ||
{ | ||
[Workflow] | ||
class MyWorkflow | ||
{ | ||
private bool shutdown; | ||
|
||
[WorkflowRun] | ||
public Task RunAsync() => Workflow.WaitConditionAsync(() => shutdown); | ||
|
||
[WorkflowSignal] | ||
public async Task ShutdownAsync() => shutdown = true; | ||
|
||
[WorkflowUpdate] | ||
public Task<int> DoActivitiesAsync() => | ||
// Run 5 activities and sum the results | ||
Task.WhenAll( | ||
Enumerable.Range(0, 5).Select(_ => | ||
Workflow.ExecuteActivityAsync( | ||
() => MyActivities.MyActivity(), | ||
new() { StartToCloseTimeout = TimeSpan.FromSeconds(5) } ))). | ||
ContinueWith(vals => Enumerable.Sum(vals.Result)); | ||
} | ||
|
||
class MyActivities | ||
{ | ||
[Activity] | ||
public static int MyActivity() => 6; | ||
} | ||
|
||
public void ConfigureWorker(Runner runner, TemporalWorkerOptions options) => | ||
options.AddWorkflow<MyWorkflow>().AddAllActivities<MyActivities>(null); | ||
|
||
public async Task<WorkflowHandle?> ExecuteAsync(Runner runner) | ||
{ | ||
await runner.SkipIfUpdateNotSupportedAsync(); | ||
var handle = await runner.Client.StartWorkflowAsync( | ||
(MyWorkflow wf) => wf.RunAsync(), | ||
runner.NewWorkflowOptions()); | ||
Assert.Equal(30, await handle.ExecuteUpdateAsync(wf => wf.DoActivitiesAsync())); | ||
await handle.SignalAsync(wf => wf.ShutdownAsync()); | ||
return handle; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
namespace update.async_accepted; | ||
|
||
using Temporalio.Activities; | ||
using Temporalio.Client; | ||
using Temporalio.Exceptions; | ||
using Temporalio.Features.Harness; | ||
using Temporalio.Worker; | ||
using Temporalio.Workflows; | ||
using Xunit; | ||
|
||
class Feature : IFeature | ||
{ | ||
[Workflow] | ||
class MyWorkflow | ||
{ | ||
private bool shutdown; | ||
private bool finishUpdate; | ||
|
||
[WorkflowRun] | ||
public Task RunAsync() => Workflow.WaitConditionAsync(() => shutdown); | ||
|
||
[WorkflowSignal] | ||
public async Task ShutdownAsync() => shutdown = true; | ||
|
||
[WorkflowSignal] | ||
public async Task FinishUpdateAsync() => finishUpdate = true; | ||
|
||
[WorkflowUpdate] | ||
public async Task<int> SuccessfulUpdateAsync() | ||
{ | ||
await Workflow.WaitConditionAsync(() => finishUpdate); | ||
finishUpdate = false; | ||
return 123; | ||
} | ||
|
||
[WorkflowUpdate] | ||
public async Task FailureUpdateAsync() | ||
{ | ||
await Workflow.WaitConditionAsync(() => finishUpdate); | ||
finishUpdate = false; | ||
throw new ApplicationFailureException("Intentional failure"); | ||
} | ||
} | ||
|
||
class MyActivities | ||
{ | ||
[Activity] | ||
public static int MyActivity() => 6; | ||
} | ||
|
||
public void ConfigureWorker(Runner runner, TemporalWorkerOptions options) => | ||
options.AddWorkflow<MyWorkflow>().AddAllActivities<MyActivities>(null); | ||
|
||
public async Task<WorkflowHandle?> ExecuteAsync(Runner runner) | ||
{ | ||
await runner.SkipIfAsyncUpdateNotSupportedAsync(); | ||
|
||
// Start workflow | ||
var handle = await runner.Client.StartWorkflowAsync( | ||
(MyWorkflow wf) => wf.RunAsync(), | ||
runner.NewWorkflowOptions()); | ||
|
||
// Start update | ||
var updateHandle1 = await handle.StartUpdateAsync(wf => wf.SuccessfulUpdateAsync()); | ||
// Send signal to finish the update | ||
await handle.SignalAsync(wf => wf.FinishUpdateAsync()); | ||
// Confirm result | ||
Assert.Equal(123, await updateHandle1.GetResultAsync()); | ||
// Create another handle and confirm its result is the same | ||
Assert.Equal(123, await handle.GetUpdateHandle<int>(updateHandle1.Id).GetResultAsync()); | ||
|
||
// Start a failed update | ||
var updateHandle2 = await handle.StartUpdateAsync(wf => wf.FailureUpdateAsync()); | ||
// Send signal to finish the update | ||
await handle.SignalAsync(wf => wf.FinishUpdateAsync()); | ||
// Confirm failure | ||
var exc = await Assert.ThrowsAsync<WorkflowUpdateFailedException>( | ||
() => updateHandle2.GetResultAsync()); | ||
Assert.Equal("Intentional failure", exc.InnerException?.Message); | ||
|
||
// Start an update but cancel/timeout waiting on its result | ||
var updateHandle3 = await handle.StartUpdateAsync(wf => wf.SuccessfulUpdateAsync()); | ||
// Wait for result only for 100ms | ||
using var tokenSource = new CancellationTokenSource(); | ||
tokenSource.CancelAfter(TimeSpan.FromMilliseconds(100)); | ||
await Assert.ThrowsAsync<OperationCanceledException>(() => | ||
updateHandle3.GetResultAsync(new() { CancellationToken = tokenSource.Token })); | ||
|
||
await handle.SignalAsync(wf => wf.ShutdownAsync()); | ||
return handle; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
harness/dotnet/Temporalio.Features.Harness/TestSkippedException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace Temporalio.Features.Harness; | ||
|
||
/// <summary> | ||
/// Exception used to skip a feature. | ||
/// </summary> | ||
public class TestSkippedException : Exception | ||
{ | ||
/// <summary> | ||
/// Create exception. | ||
/// </summary> | ||
/// <param name="message">Reason for skipping.</param> | ||
public TestSkippedException(string message) | ||
: base(message) | ||
{ | ||
} | ||
} |
Oops, something went wrong.