public static async Task Main(params string[] args) { var settings = new TemporalSettings() { // This specifies the default namespace for operations initiated by the // client connected below (this can be overridden for specific // operations). Namespace = "Acme-PROD", // Host/port for at least one of the Temporal cluster servers: HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a typed stub for the remote workflow. var stub = client.NewWorkflowStub <IMailer>(); // Execute the workflow. var success = await stub.SendEmail("*****@*****.**", "Test subject", "This is a test email."); if (success) { Console.WriteLine("Email SENT!"); } else { Console.WriteLine("Email FAILED!"); } } }
public Test_RegistrationError(TemporalFixture fixture) { var settings = new TemporalSettings() { Namespace = TemporalFixture.Namespace, ProxyLogLevel = TemporalTestHelper.ProxyLogLevel, CreateNamespace = true, Debug = TemporalTestHelper.Debug, DebugPrelaunched = TemporalTestHelper.DebugPrelaunched, DebugDisableHeartbeats = TemporalTestHelper.DebugDisableHeartbeats, ClientIdentity = TemporalTestHelper.ClientIdentity }; if (fixture.Start(settings, composeFile: TemporalTestHelper.TemporalStackDefinition, reconnect: true, keepRunning: TemporalTestHelper.KeepTemporalServerOpen) == TestFixtureStatus.Started) { this.fixture = fixture; this.client = fixture.Client; this.proxyClient = new HttpClient() { BaseAddress = client.ProxyUri }; // NOTE: We're not auto-registering workflows and activities or starting // workers for these unit tests. } else { this.fixture = fixture; this.client = fixture.Client; this.proxyClient = new HttpClient() { BaseAddress = client.ProxyUri }; } }
public Test_Replay(TemporalFixture fixture) { TestHelper.ResetDocker(this.GetType()); var settings = new TemporalSettings() { Namespace = TemporalFixture.Namespace, ProxyLogLevel = TemporalTestHelper.ProxyLogLevel, CreateNamespace = true, Debug = TemporalTestHelper.Debug, DebugPrelaunched = TemporalTestHelper.DebugPrelaunched, DebugDisableHeartbeats = TemporalTestHelper.DebugDisableHeartbeats, ClientIdentity = TemporalTestHelper.ClientIdentity, TaskQueue = TemporalTestHelper.TaskQueue }; if (fixture.Start(settings, composeFile: TemporalTestHelper.TemporalStackDefinition, reconnect: true, keepRunning: TemporalTestHelper.KeepTemporalServerOpen) == TestFixtureStatus.Started) { this.fixture = fixture; this.client = fixture.Client; // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = client.NewWorkerAsync().Result; worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()).WaitWithoutAggregate(); worker.StartAsync().WaitWithoutAggregate(); } else { this.fixture = fixture; this.client = fixture.Client; } }
public static async Task Main(string[] args) { // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterWorkflowAsync <HelloWorkflow>(); await worker.StartAsync(); // Invoke your workflow. var stub = client.NewWorkflowStub <IHelloWorkflow>(); Console.WriteLine(await stub.HelloAsync("Jeff")); } }
public Test_SignalChecks(TemporalFixture fixture) { TestHelper.ResetDocker(this.GetType()); var settings = new TemporalSettings() { Namespace = TemporalFixture.Namespace, ProxyLogLevel = TemporalTestHelper.ProxyLogLevel, CreateNamespace = true, Debug = TemporalTestHelper.Debug, DebugPrelaunched = TemporalTestHelper.DebugPrelaunched, DebugDisableHeartbeats = TemporalTestHelper.DebugDisableHeartbeats, ClientIdentity = TemporalTestHelper.ClientIdentity }; if (fixture.Start(settings, composeFile: TemporalTestHelper.TemporalStackDefinition, reconnect: true, keepRunning: TemporalTestHelper.KeepTemporalServerOpen) == TestFixtureStatus.Started) { this.fixture = fixture; this.client = fixture.Client; this.proxyClient = new HttpClient() { BaseAddress = client.ProxyUri }; } else { this.fixture = fixture; this.client = fixture.Client; this.proxyClient = new HttpClient() { BaseAddress = client.ProxyUri }; } }
public static async Task Main(string[] args) { // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", TaskQueue = "my-tasks", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()); await worker.StartAsync(); // Invoke the workflow. var workflowStub = client.NewWorkflowStub <IEmailWorkflow>(); await workflowStub.SendMessagesAsync(); } }
/// <summary> /// Creates a workflow stub instance suitable for connecting to an existing external workflow. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="dataConverter">The data converter.</param> /// <param name="workflowId">Specifies the workflow ID.</param> /// <param name="runId">Optionally specifies the workflow run ID.</param> /// <param name="namespace">Optionally specifies the namespace.</param> /// <returns>The workflow stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, IDataConverter dataConverter, string workflowId, string runId = null, string @namespace = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(dataConverter != null, nameof(dataConverter)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(workflowId), nameof(workflowId)); return(externalConstructor.Invoke(new object[] { client, dataConverter, workflowId, runId, @namespace })); }
public void Prebuild_Stubs() { // Verify that the stub builder methods don't barf. TemporalClient.BuildActivityStub <ITestActivity>(); TemporalClient.BuildWorkflowStub <ITestWorkflow>(); TemporalClient.BuildAssemblyStubs(Assembly.GetExecutingAssembly()); }
/// <summary> /// Creates a workflow stub instance suitable for continuing a workflow as new. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="dataConverter">The data converter.</param> /// <param name="workflowTypeName">Specifies the workflow type name.</param> /// <param name="options">Optionally specifies the continuation options.</param> /// <returns>The workflow stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, IDataConverter dataConverter, string workflowTypeName, ContinueAsNewOptions options = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(dataConverter != null, nameof(dataConverter)); Covenant.Requires <ArgumentNullException>(workflowTypeName != null, nameof(workflowTypeName)); return(continueConstructor.Invoke(new object[] { client, dataConverter, workflowTypeName, options })); }
/// <summary> /// Creates a stub for an existing child workflow specified by a <see cref="WorkflowExecution"/>. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="dataConverter">The data converter.</param> /// <param name="parentWorkflow">The parent workflow.</param> /// <param name="execution">The <see cref="WorkflowExecution"/>.</param> /// <returns>The workflow stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, IDataConverter dataConverter, Workflow parentWorkflow, WorkflowExecution execution) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(dataConverter != null, nameof(dataConverter)); Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow)); Covenant.Requires <ArgumentNullException>(execution != null, nameof(execution)); return(childExternalConstructor.Invoke(new object[] { client, dataConverter, parentWorkflow, execution })); }
/// <summary> /// Creates a local activity stub instance suitable for executing a non-local activity. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="workflow">The parent workflow.</param> /// <param name="activityType">The activity implementation type.</param> /// <param name="options">Specifies the <see cref="LocalActivityOptions"/> or <c>null</c>.</param> /// <returns>The activity stub as an <see cref="object"/>.</returns> public object CreateLocal(TemporalClient client, Workflow workflow, Type activityType, LocalActivityOptions options) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(workflow != null, nameof(workflow)); Covenant.Requires <ArgumentNullException>(activityType != null, nameof(activityType)); options = options ?? new LocalActivityOptions(); return(localConstructor.Invoke(new object[] { client, client.DataConverter, workflow, activityType, options, TemporalHelper.GetActivityInterface(activityType) })); }
/// <summary> /// Creates a workflow stub instance mapping to an already started child workflow. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="dataConverter">The data converter.</param> /// <param name="parentWorkflow">The parent workflow.</param> /// <param name="workflowTypeName">Specifies the workflow type name.</param> /// <param name="childExecution">The child execution information.</param> /// <returns>The workflow stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, IDataConverter dataConverter, Workflow parentWorkflow, string workflowTypeName, ChildExecution childExecution) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(dataConverter != null, nameof(dataConverter)); Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(workflowTypeName), nameof(workflowTypeName)); Covenant.Requires <ArgumentNullException>(childExecution != null, nameof(childExecution)); return(childExecutedConstructor.Invoke(new object[] { client, dataConverter, parentWorkflow, workflowTypeName, childExecution })); }
/// <summary> /// Creates a workflow stub instance suitable for starting a new external workflow. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="dataConverter">The data converter.</param> /// <param name="workflowTypeName">Specifies the workflow type name.</param> /// <param name="options">Specifies the <see cref="StartWorkflowOptions"/> or <c>null</c>.</param> /// <param name="workflowInterface">Specifies the workflow interface definition.</param> /// <returns>The workflow stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, IDataConverter dataConverter, string workflowTypeName, StartWorkflowOptions options, System.Type workflowInterface) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(dataConverter != null, nameof(dataConverter)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(workflowTypeName), nameof(workflowTypeName)); Covenant.Requires <ArgumentNullException>(workflowInterface != null, nameof(workflowInterface)); options = options ?? new StartWorkflowOptions(); return(externalStartConstructor.Invoke(new object[] { client, dataConverter, workflowTypeName, options, workflowInterface })); }
/// <summary> /// Creates a normal (non-local) activity stub instance suitable for executing a non-local activity. /// </summary> /// <param name="client">The associated <see cref="TemporalClient"/>.</param> /// <param name="workflow">The parent workflow.</param>x /// <param name="activityTypeName">Specifies the activity type name.</param> /// <param name="options">Specifies the <see cref="ActivityOptions"/> or <c>null</c>.</param> /// <param name="activityInterface">Specifies the activity interface definition.</param> /// <returns>The activity stub as an <see cref="object"/>.</returns> public object Create(TemporalClient client, Workflow workflow, string activityTypeName, ActivityOptions options, System.Type activityInterface) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(workflow != null, nameof(workflow)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(activityTypeName), nameof(activityTypeName)); Covenant.Requires <ArgumentNullException>(activityInterface != null, nameof(activityInterface)); options = options ?? new ActivityOptions(); return(normalConstructor.Invoke(new object[] { client, client.DataConverter, workflow, activityTypeName, options, activityInterface })); }
public Test_EndToEnd(TemporalFixture fixture, ITestOutputHelper outputHelper) { TestHelper.ResetDocker(this.GetType()); testWriter = new TestOutputWriter(outputHelper); // Configure a service for activity dependency injection testing if it doesn't // already exist. if (NeonHelper.ServiceContainer.GetService <ActivityDependency>() == null) { NeonHelper.ServiceContainer.AddSingleton(typeof(ActivityDependency), new ActivityDependency() { Hello = "World!" }); } // Initialize the Cadence fixture. var settings = new TemporalSettings() { Namespace = TemporalFixture.Namespace, ProxyLogLevel = TemporalTestHelper.ProxyLogLevel, CreateNamespace = true, Debug = TemporalTestHelper.Debug, DebugPrelaunched = TemporalTestHelper.DebugPrelaunched, DebugDisableHeartbeats = TemporalTestHelper.DebugDisableHeartbeats, ClientIdentity = TemporalTestHelper.ClientIdentity, TaskQueue = TemporalTestHelper.TaskQueue }; if (fixture.Start(settings, composeFile: TemporalTestHelper.TemporalStackDefinition, reconnect: true, keepRunning: TemporalTestHelper.KeepTemporalServerOpen) == TestFixtureStatus.Started) { this.fixture = fixture; this.client = fixture.Client; // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = client.NewWorkerAsync().Result; worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()).WaitWithoutAggregate(); worker.StartAsync().WaitWithoutAggregate(); } else { this.fixture = fixture; this.client = fixture.Client; } }
public async Task Simultaneous() { await SyncContext.Clear; // We're going to establish two simultaneous client connections, // register a workflow on each, and then verify that these workflows work. var client1Settings = fixture.Settings.Clone(); client1Settings.TaskQueue = "taskqueue-1"; using (var client1 = await TemporalClient.ConnectAsync(client1Settings)) { var worker1 = await client1.NewWorkerAsync(); await worker1.RegisterWorkflowAsync <WorkflowWithResult1>(); await worker1.StartAsync(); var client2Settings = fixture.Settings.Clone(); client2Settings.TaskQueue = "taskqueue-2"; using (var client2 = await TemporalClient.ConnectAsync(client2Settings)) { var worker2 = await client2.NewWorkerAsync(); await worker2.RegisterWorkflowAsync <WorkflowWithResult2>(); await worker2.StartAsync(); var options1 = new StartWorkflowOptions() { TaskQueue = "taskqueue-1" }; var options2 = new StartWorkflowOptions() { TaskQueue = "taskqueue-2" }; var stub1 = client1.NewWorkflowStub <IWorkflowWithResult1>(options: options1); var stub2 = client2.NewWorkflowStub <IWorkflowWithResult2>(options: options2); Assert.Equal("WF1 says: Hello Jeff!", await stub1.HelloAsync("Jeff")); Assert.Equal("WF2 says: Hello Jeff!", await stub2.HelloAsync("Jeff")); } } }
public static async Task UntypedStub() { #region code_untyped var settings = new TemporalSettings() { // This specifies the default namespace for operations initiated by the // client connected below (this can be overridden for specific // operations). Namespace = "Acme-PROD", // Host/port for at least one of the Temporal cluster servers: HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create an untyped stub for the remote workflow. var stub = client.NewUntypedWorkflowStub("SendEmail"); // Start the workflow. Note that we need to take to ensure that the number, order // and types of the parameters match what the GOLANG workflow implementation expects. // Untyped workflow stub arguments cannot be checked be the C# compiler. // // This method returns a [WorkflowExecution] which includes the workflow and // run IDs. We're not using these here, but real applications may want to // persist this so that could check on long-running workflows later. var execution = await stub.StartAsync("*****@*****.**", "Test subject", "This is a test email."); // Wait for the workflow to complete and return it's result. Note that we need // to explicitly specify the result [bool] type as a generic type parameter. // You need to ensure that this matches the workflow implementation as well. var success = await stub.GetResultAsync <bool>(); if (success) { Console.WriteLine("Email SENT!"); } else { Console.WriteLine("Email FAILED!"); } } #endregion }
public static async Task Main(string[] args) { // Initialize the logger. LogManager.Default.SetLogLevel("info"); logger = LogManager.Default.GetLogger(typeof(Program)); logger.LogInfo("Starting workflow service"); try { // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterAssemblyAsync(System.Reflection.Assembly.GetExecutingAssembly()); await worker.StartAsync(); // Spin forever, processing workflows and activities assigned by Temporal. while (true) { await Task.Delay(TimeSpan.FromMinutes(5)); } } } catch (Exception e) { logger.LogError(e); } finally { logger.LogInfo("Exiting workflow service"); } }
public TemporalTests(TemporalFixture fixture) { TestHelper.ResetDocker(this.GetType()); var settings = new TemporalSettings() { Namespace = "test-domain", TaskQueue = "test-tasks", ProxyLogLevel = LogLevel.Info, CreateNamespace = true // <-- this ensures that the default namespace exists }; // This starts/restarts the [nforgeio/temporal-dev] container for the first test // run in this class. Subsequent tests run from the class will use the existing // container instance, saving time by not having to wait for Temporal and Cassandra // to spin up and be ready for business. // // The [keepOpen=true] parameter tells the fixture to let the container continue running // after all of the tests have completed. This is useful for examining workflow histories // via the Temporal UX after the tests have completed. You can view the Temporal portal at // // http://localhost:8088 // // You can pass [keepOpen=false] to have the fixture remove the container after the // test run if you wish. if (fixture.Start(settings, reconnect: true, keepRunning: true) == TestFixtureStatus.Started) { this.fixture = fixture; this.client = fixture.Client; // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = client.NewWorkerAsync().Result; worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()).WaitWithoutAggregate(); worker.StartAsync().WaitWithoutAggregate(); } else { this.fixture = fixture; this.client = fixture.Client; } }
public async Task Workflow_ExternalIdNoReuse() { await SyncContext.Clear; // Verify that default Cadence settings allow duplicate workflow IDs // and then change this to prevent reuse. var settings = fixture.Settings.Clone(); Assert.Equal(WorkflowIdReusePolicy.AllowDuplicate, settings.WorkflowIdReusePolicy); settings.WorkflowIdReusePolicy = WorkflowIdReusePolicy.RejectDuplicate; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = client.NewWorkerAsync().Result; worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()).WaitWithoutAggregate(); worker.StartAsync().WaitWithoutAggregate(); // Do the first run; this should succeed. var options = new StartWorkflowOptions() { Id = $"Workflow_ExternalIdNoReuse-{Guid.NewGuid().ToString("d")}" }; var stub = client.NewWorkflowStub <IWorkflowIdReuse>(options); Assert.Equal("Hello Jack!", await stub.HelloAsync("Jack")); // Do the second run with the same ID. This shouldn't actually start // another workflow and will return the result from the original // workflow instead. stub = client.NewWorkflowStub <IWorkflowIdReuse>(options); Assert.Equal("Hello Jack!", await stub.HelloAsync("Jill")); } }
public static async Task Main(string[] args) { // Configure the settings name such that they will be injected // into the email activity when it's constructed. // // Note that we did this before calling RegisterAssemblyAsync() below. // Dependencies added after activities have been registered will be // ignored. NeonHelper.ServiceContainer.AddSingleton(typeof(MailSettings), new MailSettings() { MailServer = "mail.my-company.com" }); // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", TaskQueue = "my-tasks", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()); await worker.StartAsync(); // Invoke the workflow. var workflowStub = client.NewWorkflowStub <IEmailWorkflow>(); await workflowStub.SendMessagesAsync(); } }
public static async Task Main(string[] args) { var settings = new TemporalSettings() { Namespace = "my-namespace", TaskQueue = "my-tasks", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()); await worker.StartAsync(); // Invoke the workflow, send it some signals and very that // it changed its state to the signal value. var stub = client.NewWorkflowStub <IMyWorkflow>(); var task = stub.DoItAsync(); await stub.SignalAsync("signal #1"); Console.WriteLine(await stub.GetStatusAsync()); await stub.SignalAsync("signal #2"); Console.WriteLine(await stub.GetStatusAsync()); // This signal completes the workflow. await stub.SignalAsync("done"); await task; } }
public async Task Connect_Twice() { await SyncContext.Clear; // We're going to establish two successive client connections // and verify that these work. var settings1 = fixture.Settings.Clone(); var settings2 = fixture.Settings.Clone(); settings1.TaskQueue = "taskqueue-3"; settings2.TaskQueue = "taskqueue-4"; using (var client = await TemporalClient.ConnectAsync(settings1)) { using (var worker = await client.NewWorkerAsync()) { await worker.RegisterWorkflowAsync <WorkflowWithResult3>(); await worker.StartAsync(); var stub = client.NewWorkflowStub <IWorkflowWithResult3>(); Assert.Equal("WF3 says: Hello Jack!", await stub.HelloAsync("Jack")); } } using (var client = await TemporalClient.ConnectAsync(settings2)) { using (var worker = await client.NewWorkerAsync()) { await worker.RegisterWorkflowAsync <WorkflowWithResult4>(); await worker.StartAsync(); var stub = client.NewWorkflowStub <IWorkflowWithResult4>(); Assert.Equal("WF4 says: Hello Jack!", await stub.HelloAsync("Jack")); } } }
public Test_StubManager(TemporalFixture fixture) { TestHelper.ResetDocker(this.GetType()); var settings = new TemporalSettings() { Namespace = TemporalFixture.Namespace, ProxyLogLevel = TemporalTestHelper.ProxyLogLevel, Debug = TemporalTestHelper.Debug, ClientIdentity = TemporalTestHelper.ClientIdentity }; fixture.Start(settings, reconnect: true); this.fixture = fixture; this.client = fixture.Client; this.proxyClient = new HttpClient() { BaseAddress = client.ProxyUri }; }
public async Task Workflow_ExternalIdReuseViaSettings() { await SyncContext.Clear; // Verify that default Cadence settings allow duplicate workflow IDs. var settings = fixture.Settings.Clone(); Assert.Equal(WorkflowIdReusePolicy.AllowDuplicate, settings.WorkflowIdReusePolicy); using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = client.NewWorkerAsync().Result; worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()).WaitWithoutAggregate(); worker.StartAsync().WaitWithoutAggregate(); // Do the first run. var options = new StartWorkflowOptions() { Id = $"Workflow_ExternalIdReuseViaOptions-{Guid.NewGuid().ToString("d")}" }; var stub = client.NewWorkflowStub <IWorkflowIdReuse>(options); Assert.Equal("Hello Jack!", await stub.HelloAsync("Jack")); // Do the second run. stub = client.NewWorkflowStub <IWorkflowIdReuse>(options); Assert.Equal("Hello Jill!", await stub.HelloAsync("Jill")); } }
public static async Task Main(string[] args) { // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", TaskQueue = "my-tasks", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterWorkflowAsync <HelloWorkflow>(); await worker.StartAsync(); #region code // Invoke a workflow with options: var stub = client.NewWorkflowStub <IHelloWorkflow>( new StartWorkflowOptions() { Id = "my-ultimate-workflow", WorkflowRunTimeout = TimeSpan.FromMinutes(5) }); Console.WriteLine(await stub.HelloAsync("Jeff")); #endregion } }
public static async Task Main(string[] args) { // Connect to Temporal var settings = new TemporalSettings() { Namespace = "my-namespace", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { var stub = client.NewWorkflowFutureStub <ICronWorkflow>( "backup", new StartWorkflowOptions() { // Run the workflow every day at 1:00am UTC: CronSchedule = "0 1 * * *" });; await stub.StartAsync(); } }
public void Base_ExtractTemporalProxy() { // Verify that we can extract the [temporal-proxy] binaries. using (var folder = new TempFolder()) { TemporalClient.ExtractTemporalProxy(folder.Path); var names = new string[] { "temporal-proxy.win.exe", "temporal-proxy.linux", "temporal-proxy.osx" }; foreach (var name in names) { var fullPath = Path.Combine(folder.Path, name); Assert.True(File.Exists(fullPath)); Assert.True(new FileInfo(fullPath).Length > 0); } } }
public static async Task Main(string[] args) { var settings = new TemporalSettings() { Namespace = "my-namespace", TaskQueue = "my-tasks", CreateNamespace = true, HostPort = "localhost:7933" }; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. var worker = await client.NewWorkerAsync(); await worker.RegisterAssemblyAsync(System.Reflection.Assembly.GetExecutingAssembly()); await worker.StartAsync(); // Invoke the workflow and then query it's status a few times. var stub = client.NewWorkflowStub <IMyWorkflow>(); var task = stub.DoItAsync(); for (int i = 0; i < 5; i++) { await Task.Delay(TimeSpan.FromSeconds(2.5)); Console.WriteLine(await stub.GetStatusAsync()); } await task; } }
/// <inheritdoc/> protected async override Task <int> OnRunAsync() { // Verify the environment variables. var settings = new TemporalSettings(); var hostPort = GetEnvironmentVariable("TEMPORAL_HOSTPORT"); var @namespace = GetEnvironmentVariable("TEMPORAL_NAMESPACE"); var taskQueue = GetEnvironmentVariable("TEMPORAL_TASKQUEUE"); var error = false; Log.LogInfo(() => $"TEMPORAL_HOSTPORT: {hostPort}"); Log.LogInfo(() => $"TEMPORAL_NAMESPACE: {@namespace}"); Log.LogInfo(() => $"TEMPORAL_TASKQUEUE: {taskQueue}"); if (string.IsNullOrEmpty(hostPort)) { error = true; Log.LogError("The [TEMPORAL_HOSTPORT] environment variable is required."); } settings.HostPort = hostPort; if (string.IsNullOrEmpty(@namespace)) { error = true; Log.LogError("The [TEMPORAL_NAMESPACE] environment variable is required."); } if (string.IsNullOrEmpty(taskQueue)) { error = true; Log.LogError("The [TEMPORAL_TASKQUEUE] environment variable is required."); } if (error) { return(1); } // Connect to Temporal and register the workflows and activities. Log.LogInfo("Connecting to Temporal."); settings.Namespace = @namespace; settings.TaskQueue = taskQueue; using (var client = await TemporalClient.ConnectAsync(settings)) { // Create a worker and register the workflow and activity // implementations to let Temporal know we're open for business. using (var worker = await client.NewWorkerAsync()) { Log.LogInfo("Registering workflows."); await worker.RegisterAssemblyAsync(Assembly.GetExecutingAssembly()); Log.LogInfo("Starting worker."); await worker.StartAsync(); // Indicate that the service is running. Log.LogInfo("Ready for work."); await StartedAsync(); } } // Handle termination gracefully. await Terminator.StopEvent.WaitAsync(); Terminator.ReadyToExit(); return(0); }