Ejemplo n.º 1
0
        /// <summary>
        /// Registers a workflow implementation with Temporal.
        /// </summary>
        /// <typeparam name="TWorkflow">The <see cref="WorkflowBase"/> derived class implementing the workflow.</typeparam>
        /// <param name="disableDuplicateCheck">Disable checks for duplicate registrations.</param>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        /// <exception cref="InvalidOperationException">
        /// Thrown if the worker has already been started.  You must register workflow
        /// and activity implementations before starting workers.
        /// </exception>
        /// <remarks>
        /// <note>
        /// Be sure to register all of your workflow implementations before starting a worker.
        /// </note>
        /// </remarks>
        public async Task RegisterWorkflowAsync <TWorkflow>(bool disableDuplicateCheck = false)
            where TWorkflow : WorkflowBase
        {
            await SyncContext.Clear;

            TemporalHelper.ValidateWorkflowImplementation(typeof(TWorkflow));
            EnsureNotDisposed();
            EnsureCanRegister();

            var workflowType = typeof(TWorkflow);

            lock (registeredWorkflowTypes)
            {
                if (registeredWorkflowTypes.Contains(workflowType))
                {
                    if (disableDuplicateCheck)
                    {
                        return;
                    }
                    else
                    {
                        throw new RegistrationException($"Workflow implementation [{workflowType.FullName}] has already been registered.");
                    }
                }

                registeredWorkflowTypes.Add(workflowType);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Registers a workflow implementation with temporal-proxy.
        /// </summary>
        /// <param name="workflowType">The workflow implementation type.</param>
        /// <exception cref="RegistrationException">Thrown when there's a problem with the registration.</exception>
        private async Task RegisterWorkflowImplementationAsync(Type workflowType)
        {
            await SyncContext.Clear;

            TemporalHelper.ValidateWorkflowImplementation(workflowType);

            var methodMap = WorkflowMethodMap.Create(workflowType);

            // We need to register each workflow method that implements a workflow interface method
            // with the same signature that that was tagged by [WorkflowMethod].
            //
            // First, we'll create a dictionary that maps method signatures from any inherited
            // interfaces that are tagged by [WorkflowMethod] to the attribute.

            var methodSignatureToAttribute = new Dictionary <string, WorkflowMethodAttribute>();

            foreach (var interfaceType in workflowType.GetInterfaces())
            {
                foreach (var method in interfaceType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                {
                    var workflowMethodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>();

                    if (workflowMethodAttribute == null)
                    {
                        continue;
                    }

                    var signature = method.ToString();

                    if (methodSignatureToAttribute.ContainsKey(signature))
                    {
                        throw new NotSupportedException($"Workflow type [{workflowType.FullName}] cannot implement the [{signature}] method from two different interfaces.");
                    }

                    methodSignatureToAttribute.Add(signature, workflowMethodAttribute);
                }
            }

            // Next, we need to register the workflow methods that implement the
            // workflow interface.

            foreach (var method in workflowType.GetMethods())
            {
                if (!methodSignatureToAttribute.TryGetValue(method.ToString(), out var workflowMethodAttribute))
                {
                    continue;
                }

                var workflowTypeName = TemporalHelper.GetWorkflowTypeName(workflowType, workflowMethodAttribute);

                lock (nameToWorkflowRegistration)
                {
                    if (nameToWorkflowRegistration.TryGetValue(workflowTypeName, out var existingRegistration))
                    {
                        if (!object.ReferenceEquals(existingRegistration.WorkflowType, workflowType))
                        {
                            throw new InvalidOperationException($"Conflicting workflow interface registration: Workflow interface [{workflowType.FullName}] is already registered for workflow type name [{workflowTypeName}].");
                        }
                    }
                    else
                    {
                        nameToWorkflowRegistration[workflowTypeName] =
                            new WorkflowRegistration()
                        {
                            WorkflowType   = workflowType,
                            WorkflowMethod = method,
                            WorkflowMethodParameterTypes = method.GetParameterTypes(),
                            MethodMap = methodMap
                        };
                    }
                }

                var reply = (WorkflowRegisterReply)await Client.CallProxyAsync(
                    new WorkflowRegisterRequest()
                {
                    WorkerId = WorkerId,
                    Name     = workflowTypeName,
                });

                reply.ThrowOnError();
            }
        }