Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add F# examples #92

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion TemporalioSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemporalioSamples.Bedrock.S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TemporalioSamples.Bedrock.Entity", "src\Bedrock\Entity\TemporalioSamples.Bedrock.Entity.csproj", "{AE18875F-B7D2-4A3C-8784-15B76277D508}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "TemporalioSamples.ActivitySimpleFSharp", "src\ActivitySimpleFSharp\TemporalioSamples.ActivitySimpleFSharp.fsproj", "{4C012387-390E-4979-AA0E-2B256A0A8ECB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -209,6 +211,10 @@ Global
{AE18875F-B7D2-4A3C-8784-15B76277D508}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE18875F-B7D2-4A3C-8784-15B76277D508}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE18875F-B7D2-4A3C-8784-15B76277D508}.Release|Any CPU.Build.0 = Release|Any CPU
{4C012387-390E-4979-AA0E-2B256A0A8ECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C012387-390E-4979-AA0E-2B256A0A8ECB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C012387-390E-4979-AA0E-2B256A0A8ECB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C012387-390E-4979-AA0E-2B256A0A8ECB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -242,9 +248,10 @@ Global
{F9C44936-8BF9-4919-BB66-8F1888E22AEB} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
{751E0AF8-62EE-4220-A571-D1C53DD0D45A} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
{4EA37A92-E4D5-4348-AF2F-0CAE37A1E079} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
{5339989C-3791-4D75-A9F1-42620C443D4A} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
{5339989C-3791-4D75-A9F1-42620C443D4A} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
{CC3487CB-F795-4CA9-A4F6-28C145AE383B} = {5339989C-3791-4D75-A9F1-42620C443D4A}
{4E69DE72-E972-4155-B4D1-ABFE0B054ECF} = {5339989C-3791-4D75-A9F1-42620C443D4A}
{AE18875F-B7D2-4A3C-8784-15B76277D508} = {5339989C-3791-4D75-A9F1-42620C443D4A}
{4C012387-390E-4979-AA0E-2B256A0A8ECB} = {1A647B41-53D0-4638-AE5A-6630BAAE45FC}
EndGlobalSection
EndGlobal
105 changes: 105 additions & 0 deletions src/ActivitySimpleFSharp/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
module Activities =
open Temporalio.Activities

type MyDatabseClient() =
member this.SelectValueAsync(table: string) =
task {
return $"some-db-value from table {table}"
}

type MyActivities() =
let databaseClient = MyDatabseClient()
[<Activity>]
member this.SelectFromDatabaseAsync(table: string) =
task {
return! databaseClient.SelectValueAsync(table)
}

[<Activity>]
static member DoStaticThing() =
"some-static-value"

module Workflows =
open Temporalio.Workflows
open Microsoft.Extensions.Logging
open System

[<Workflow>]
type MyWorkflow() =

[<WorkflowRun>]
member this.RunAsync() =
task {
// Run an async instance method activity.
// Note that in F# the generic types can not be inferred since the Temporal API
// uses overloads which leads to overload resolution ambiguity. We need to specify the generic types explicitly.
let! result1 = Workflow.ExecuteActivityAsync<Activities.MyActivities, string>(
(fun (act: Activities.MyActivities) -> act.SelectFromDatabaseAsync("some-db-table")),
ActivityOptions( StartToCloseTimeout = TimeSpan.FromSeconds(5)))
Workflow.Logger.LogInformation("Activity instance method result: {Result}", result1);

// Run a sync static method activity.
let! result2 = Workflow.ExecuteActivityAsync<string>(
(fun _ -> Activities.MyActivities.DoStaticThing()),
ActivityOptions( StartToCloseTimeout = TimeSpan.FromSeconds(5)))
Workflow.Logger.LogInformation("Activity static method result: {Result}", result2);

// We'll go ahead and return this result
return result2;
}

module Main =
open System
open Microsoft.Extensions.Logging
open Temporalio.Client
open Temporalio.Worker
open System.Threading

// Create a client to localhost on default namespace
let client = TemporalClient.ConnectAsync(TemporalClientConnectOptions(
"localhost:7233",
LoggerFactory = LoggerFactory.Create(fun builder ->
builder.
AddSimpleConsole(fun options -> options.TimestampFormat = "[HH:mm:ss] " |> ignore).
SetMinimumLevel(LogLevel.Information) |> ignore)
)).Result

let runWorkerAsync() =
// Cancellation token cancelled on ctrl+c
use tokenSource = new CancellationTokenSource()
Console.CancelKeyPress.Add(fun eventArgs ->
tokenSource.Cancel()
eventArgs.Cancel <- true
)

// Create an activity instance with some state
let activities = Activities.MyActivities()

// Run worker until cancelled
Console.WriteLine("Running worker")
use worker = new TemporalWorker(
client, TemporalWorkerOptions( "activity-simple-sample").AddWorkflow<Workflows.MyWorkflow>().AddAllActivities<Activities.MyActivities>(activities)
)
try
worker.ExecuteAsync(tokenSource.Token) |> Async.AwaitTask |> Async.RunSynchronously
with
| :? OperationCanceledException ->
Console.WriteLine("Worker cancelled")

let executeWorkflowAsync() =
Console.WriteLine("Executing workflow")
client.ExecuteWorkflowAsync(
(fun (wf: Workflows.MyWorkflow) -> wf.RunAsync()),
WorkflowOptions(id = "activity-simple-workflow-id", taskQueue = "activity-simple-sample")
)

[<EntryPoint>]
let main args =
match Array.head args with
| "worker" ->
runWorkerAsync()
0
| "workflow" ->
executeWorkflowAsync() |> Async.AwaitTask |> Async.RunSynchronously |> ignore
0
| _ -> failwith "Must pass 'worker' or 'workflow' as the single argument"
15 changes: 15 additions & 0 deletions src/ActivitySimpleFSharp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Activity Simple - F#

This sample shows a workflow executing a synchronous static activity method and an asynchronous instance activity
method using F#

To run, first see [README.md](../../README.md) for prerequisites. Then, run the following from this directory
in a separate terminal to start the worker:

dotnet run worker

Then in another terminal, run the workflow from this directory:

dotnet run workflow

This will show logs in the worker window of the workflow running.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>

</Project>
Loading