Releases: temporalio/sdk-dotnet
0.1.0-alpha6
Get from NuGet and read the README
Highlights
This release introduced two extensions and multiple other helpful features.
Activity dependency injection and generic host support for workers
A new NuGet extension at Temporalio.Extensions.Hosting is now available that adds helpers for adding activities on a service collection that support constructor dependency injection, and adds helpers for running workers as .NET generic hosts. Here's a simple example of creating a .NET host with DI-supported activities:
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Temporalio.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Add a hosted Temporal worker which returns a builder to add activities and workflows
builder.Services.
AddHostedTemporalWorker("my-temporal-host:7233", "my-namespace", "my-task-queue").
AddScopedActivities<MyActivityClass>().
AddWorkflow<MyWorkflow>();
// Run
var host = builder.Build();
host.Run();
See the README on that project for more details.
OpenTelemetry support
A new NuGet extension at Temporalio.Extensions.OpenTelemetry is now available that supports tracing clients, activities, and workflows via OpenTelemetry. This is implemented similar to how we do in our other SDKs and even compatible with them in cross-language scenarios. OpenTelemetry support is built as an interceptor leveraging .NET diagnostic activities and takes care to serialize/deserialize spans across the server boundary so even separate. There are some caveats to be aware of with regards to how OpenTelemetry spans and .NET diagnostic activities behave on workflow replay since spans/activities cannot be resumed. See the README on that project for more details.
Reenable thread pool task checker - 💥 BREAKING CHANGE
In previous versions of the .NET SDK, a tool was on by default to make sure users didn't accidentally schedule tasks from a workflow onto the .NET thread pool. This is needed because it is very easy to accidentally do. This tool was inadvertently disabled by default in the past couple of versions, but has been properly reenabled. This is therefore technically a backwards incompatible behavior change because workflows written within the past couple of versions may now break if they were written improperly.
Dynamic activities, workflows, signals, and queries
Users can now register dynamic activities, workflows, signals, and queries to be invoked as catch-all implementations with raw input payloads when there is not a named item already registered when called. The [Activity]
, [Workflow]
, [WorkflowSignal]
, and [WorkflowQuery]
attributes now all support a Dynamic = true
property. When an activity or workflow is invoked on a worker with no matching name, the dynamic form will be invoked with IRawValue[]
arguments. When a signal or query is called on a workflow with no matching name, the dynamic form will be invoked with a string name and IRawValue[]
arguments. Workers can only have one dynamic activity and one dynamic workflow since it is the fall through. Similarly, workflows can only have one dynamic signal and one dynamic query.
Queries can be properties
The getter of a property can now be used as a query. For example, in this workflow:
[Workflow]
public class MyWorkflow
{
[WorkflowRun]
public Task RunAsync()
{
await Workflow.DelayAsync(5000);
TimerDone = true;
}
[WorkflowQuery]
public bool TimerDone { get; set; }
}
Can be invoked on a client like:
var myClient = await TemporalClient.ConnectAsync("localhost:7233");
// Start workflow
var myHandle = await myClient.StartWorkflowAsync(
(MyWorkflow wf) => wf.RunAsync(),
new(id: "my-workflow-id", taskQueue: "my-task-queue"));
// Query, wait, query again
Console.WriteLine("Done? {0}", await myHandle.QueryAsync(wf => wf.TimerDone));
await Task.Delay(7000);
Console.WriteLine("Done? {0}", await myHandle.QueryAsync(wf => wf.TimerDone));
Designs were considered and rejected for making signals be property setters (but lambda expression trees disallow assignment operators) and activities be property getters (but it is rare/discouraged to make an entire activity a property).
Update test workflow environment local server
The server backing Temporalio.Testing.WorkflowEnvironment.StartLocalAsync()
has been upgraded from Temporalite with server version 1.18.1
, to the latest Temporal CLI dev server with just-released server version 1.21.0
.
Return collections instead of enumerables - 💥BREAKING CHANGE
IPayloadCodec
methods now require Task<IReadOnlyCollection<Payload>>
instead of enumerables as before. People were getting confused on when mutation would occur when creating lazy linq-based enumerables. Also affects a couple of enumerable properties.
Workflow.WhenAnyAsync added
Due to this issue, Task.WhenAny
cannot be trusted to use the current task scheduler in all cases (only most of the time). Therefore a Workflow.WhenAnyAsync
helper has been created that is guaranteed to use the current deterministic task scheduler.
Deterministic random with 64-bit seed
A stable, portable, deterministic implementation of System.Random
that is initialized with a 64-bit seed is now returned from Workflow.Random
. Before, that would return the basic System.Random
constructed with a 32-bit seed which is also not technically portable across .NET Framework versions.
Specific Changes
2023-06-06 - 4a99c2f - Add Semgrep scanning (#81)
2023-06-07 - 746d81a - OpenTelemetry Support (#83)
2023-06-13 - 12ae2b3 - Return collection instead of enumerable and fix/re-enable task scheduler check (💥 BREAKING CHANGES) (#87)
2023-06-14 - 1134b91 - Support query properties and disallow static signals/queries (#88)
2023-06-16 - b9edda0 - Dynamic workflows, activities, signals, and queries (#89)
2023-06-26 - 97e1b08 - Remove unused log that includes injection vulnerability. (#91)
2023-06-28 - 01946ba - Dependency injection hosting extension (#92)
2023-06-28 - 98ab973 - Switch from Temporalite to Temporal CLI for local server and other changes related to server update (#94)
2023-06-28 - ebaf1af - Random with 64-bit seed (#93)
0.1.0-alpha5
Get from NuGet and read the README
Highlights
This release significantly altered the way workflows, activities, signals, queries, etc are invoked. See breaking changes below.
Expression trees - 💥 BREAKING CHANGE
By popular demand, changed from "Ref" pattern to invoke workflows/activities/signals/queries to expression trees.
For example, if you used to:
await myClient.ExecuteWorkflowAsync(MyWorkflowClass.Ref.RunAsync, "my-arg", myOptions);
You will get a compile error. You have to change to:
await myClient.ExecuteWorkflowAsync((MyWorkflowClass wf) => wf.RunAsync("my-arg"), myOptions);
This breaking change applies to the following calls:
Temporalio.Client.ITemporalClient.ExecuteWorkflowAsync
(extension)Temporalio.Client.ITemporalClient.StartWorkflowAsync
Temporalio.Client.Schedules.ScheduleActionStartWorkflow.Create
Temporalio.Client.WorkflowHandle.QueryAsync
Temporalio.Client.WorkflowHandle.SignalAsync
Temporalio.Workflows.ChildWorkflowHandle.SignalAsync
Temporalio.Workflows.ExternalWorkflowHandle.SignalAsync
Temporalio.Workflows.Workflow.CreateContinueAsNewException
Temporalio.Workflows.Workflow.ExecuteActivityAsync
Temporalio.Workflows.Workflow.ExecuteChildWorkflowAsync
Temporalio.Workflows.Workflow.ExecuteLocalActivityAsync
Temporalio.Workflows.Workflow.StartChildWorkflowAsync
Also, all uses of Refs
, ActivityRefs
, and WorkflowRefs
will fail compilation now because those classes no longer exist. See PR #75 for more details.
Clearer workflow/activity worker options - 💥 BREAKING CHANGE
In order to support more advanced definitions and better practices, we have changed the TemporalWorkerOptions.Activities
from List<Delegate>
to List<ActivityDefinition>
and TemporalWorkerOptions.Workflows
from List<Type>
to List<WorkflowDefinition>
. Users should now use AddActivity
and AddWorkflow
methods to add activities and workflows to worker options
For example, if you used to do this to build your worker options:
var options = new TemporalWorkerOptions("my-task-queue")
{
Activities = { MyActivityClass.Method1, MyActivityClass.Method2 },
Workflows = { MyWorkflowClass1, MyWorkflowClass2 },
};
You will get a compile error. You have to change to:
var options = new TemporalWorkerOptions("my-task-queue").
AddActivity(MyActivityClass.Method1).
AddActivity(MyActivityClass.Method2).
AddWorkflow<MyWorkflowClass1>().
AddWorkflow<MyWorkflowClass2>();
There are also some changes in manual definition building if those were in use. See PR #67 for more details.
DataConverter just takes direct payload/failure converter instances instead of types - 💥 BREAKING CHANGE
Previously we required that when creating a custom PayloadConverter
or FailureConverter
, you had to provide a type since we planned on sandboxing them. But since it's become obvious in-runtime sandboxing is unreasonable, we made this easier so now you only have to provide instances to those converters. Still, make sure all conversions are deterministic.
Classes in Temporalio moved to Temporalio.Common - 💥 BREAKING CHANGE
The following classes were moved from Temporalio
to Temporalio.Common
:
RetryPolicy
SearchAttributeCollection
SearchAttributeKey
WorkflowHistory
See PR #80 for more details.
Specific Changes
2023-05-17 - 2efd6f4 - Update docfx (#68)
2023-05-17 - 523bdfe - Remove sandbox strictness and make more hackable (💥 BREAKING CHANGES) (#67)
2023-05-17 - c879008 - Simple benchmarker (#69)
2023-05-23 - b40efff - Support setting metadata (i.e. headers) on connection (#73)
2023-05-23 - e85959a - Add cloud test and vercel.json (#74)
2023-05-25 - 3000d51 - Fix event unset issue on time-skipping server (#78)
2023-05-25 - bbb10ab - Use expression trees for all type-safe remote calls (💥 BREAKING CHANGES) (#75)
2023-05-25 - c8c628d - Replace Go kitchen sink worker with .NET one (#72)
2023-05-26 - fd41c34 - Move Temporalio classes to Temporalio.Common (💥 BREAKING CHANGES) (#80)
0.1.0-alpha4
Get from NuGet and read the README
Highlights
Schedules
The full schedule API is now present. If you are running the latest open source server you can use the new scheduling feature to make advanced workflow execution schedules. Temporal cloud coming soon.
💥 Breaking Changes
None
Specific Changes
2023-04-25 - bb1671e - Schedule API (#53)
2023-05-01 - 3abee68 - Add banner to README (#58)
2023-05-01 - f4b1fd1 - Update core and release version (#57)
0.1.0-alpha3
Get from NuGet and read the README
Highlights
🎉Full Workflow Support!
With full workflow support of all Temporal workflow features, this SDK is now a full-featured SDK on par with all other
SDKs. The SDK is alpha due to immaturity, not incompleteness.
See the README for how to write workflows.
💥 Breaking Changes
Temporalio.Activity
namespace is nowTemporalio.Activities
- This was done to align with
Temporalio.Workflows
plural since we need theWorkflow
class name not to clash with
the namespace name
- This was done to align with
Temporalio.Activity.ActivityContext
class is nowTemporalio.Activities.ActivityExecutionContext
- This was done to avoid clashing with
System.Diagnostics.ActivityContext
- This was done to avoid clashing with
Temporalio.Refs
class is nowTemporalio.Activities.ActivityRefs
orTemporalio.Activities.WorkflowRefs
- This was done so people don't have to import
Temporalio
just for making aRef
- This was done so people don't have to import
- Default constructor for
Temporalio.Converters.DataConverter
removed- It was simply the default, which is now available as
Default
and can be used viawith
to make changes since it's
a record
- It was simply the default, which is now available as
- Search attributes and memos are now in a more type safe form
- Maybe some other minor pieces
Specific Changes
2023-02-13 - 60b2ecc - Exclude static-class check on smoke test (#21)
2023-03-01 - 43dfe89 - Renaming Activity and Workflow packages to Activities and Workflows (#26)
2023-03-07 - 2043879 - Initial workflow runtime (#29)
2023-03-10 - 838ca06 - Workflow signals, queries, and more (#31)
2023-03-20 - bed227e - Search attributes, memos, and other updates (#34)
2023-03-24 - a116fda - Workflow support for activities, children, and continue as new (#39)
2023-04-04 - cc74443 - Fixed small typo in README (#43)
2023-04-13 - b8919a4 - Misc workflow features (#40)
2023-04-19 - 3408d01 - Workflow replayer, docs, time-skipping test server, rename ActivityContext, core update, and more (#48)
0.1.0-alpha2
Get from NuGet and read the README
Highlights
Activity Worker
You can now run activities in .NET invoked by workflows in other languages
This release does not include:
- Workflow worker support
See the README for more information.
Specific Changes
2023-02-02 - 2377c7c - Doc fixes (#17)
2023-02-09 - 5e56919 - Activity worker (#18)
0.1.0-alpha1
Get from NuGet and read the README
Highlights
Initial release!
This release includes:
- Ability to define workflows in a type-safe way for client use
- Full-featured Temporal client
- Support for Windows x64, macOS x64/arm, and Linux x64/arm (glibc >= 2.31)
This release does not include:
- Activity worker support
- Workflow worker support
See the README for more information.
Specific Changes
2022-12-13 - 5847d29 - Initial commit
2023-01-06 - f43363d - Initial client and bridge (#1)
2023-01-09 - 0aa5f5e - GitHub CI action (#6)
2023-01-10 - 48d610a - Minor doc fix (#9)
2023-01-10 - 6664bc1 - Proper runtime with telemetry options (#7)
2023-01-12 - 7a4abc9 - Converters and Failure Exceptions (#11)
2023-01-16 - 932ff67 - Code formatting and StyleCop Analyzers (#13)
2023-01-30 - 468f35d - Initial workflow client (#14)
2023-02-02 - d346ffa - Release CI and README updates (#16)