Exemple #1
0
        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!");
                }
            }
        }
Exemple #2
0
        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
                };
            }
        }
Exemple #3
0
        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;
            }
        }
Exemple #4
0
        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"));
            }
        }
Exemple #5
0
        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
                };
            }
        }
Exemple #6
0
        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();
            }
        }
Exemple #7
0
        /// <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 }));
        }
Exemple #8
0
        public void Prebuild_Stubs()
        {
            // Verify that the stub builder methods don't barf.

            TemporalClient.BuildActivityStub <ITestActivity>();
            TemporalClient.BuildWorkflowStub <ITestWorkflow>();
            TemporalClient.BuildAssemblyStubs(Assembly.GetExecutingAssembly());
        }
Exemple #9
0
        /// <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 }));
        }
Exemple #10
0
        /// <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 }));
        }
Exemple #11
0
        /// <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) }));
        }
Exemple #12
0
        /// <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 }));
        }
Exemple #13
0
        /// <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 }));
        }
Exemple #14
0
        /// <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 }));
        }
Exemple #15
0
        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;
            }
        }
Exemple #16
0
        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"));
                }
            }
        }
Exemple #17
0
        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
        }
Exemple #18
0
        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");
            }
        }
Exemple #19
0
        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;
            }
        }
Exemple #20
0
        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"));
            }
        }
Exemple #21
0
        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();
            }
        }
Exemple #22
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(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;
            }
        }
Exemple #23
0
        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"));
                }
            }
        }
Exemple #24
0
        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
            };
        }
Exemple #25
0
        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"));
            }
        }
Exemple #26
0
        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
            }
        }
Exemple #27
0
        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();
            }
        }
Exemple #28
0
        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);
                }
            }
        }
Exemple #29
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;
            }
        }
Exemple #30
0
        /// <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);
        }