//--------------------------------------------------------------------- // Static members /// <summary> /// <b>INTERNAL USE ONLY:</b> Normalizes the options passed by creating or cloning a new /// instance as required and filling unset properties using default client settings. /// </summary> /// <param name="client">The associated Cadence client.</param> /// <param name="options">The input options or <c>null</c>.</param> /// <param name="workflowInterface">Optionally specifies the workflow interface definition.</param> /// <param name="method">Optionally specifies the target workflow method.</param> /// <returns>The normalized options.</returns> /// <exception cref="ArgumentNullException">Thrown if a valid task list is not specified.</exception> public static ChildWorkflowOptions Normalize(CadenceClient client, ChildWorkflowOptions options, Type workflowInterface = null, MethodInfo method = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); WorkflowInterfaceAttribute interfaceAttribute = null; WorkflowMethodAttribute methodAttribute = null; if (options == null) { options = new ChildWorkflowOptions(); } else { options = options.Clone(); } if (workflowInterface != null) { CadenceHelper.ValidateWorkflowInterface(workflowInterface); interfaceAttribute = workflowInterface.GetCustomAttribute <WorkflowInterfaceAttribute>(); } if (method != null) { methodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>(); } if (string.IsNullOrEmpty(options.Domain)) { if (!string.IsNullOrEmpty(methodAttribute?.Domain)) { options.Domain = methodAttribute.Domain; } if (string.IsNullOrEmpty(options.Domain) && !string.IsNullOrEmpty(interfaceAttribute?.Domain)) { options.Domain = interfaceAttribute.Domain; } } if (string.IsNullOrEmpty(options.TaskList)) { if (!string.IsNullOrEmpty(methodAttribute?.TaskList)) { options.TaskList = methodAttribute.TaskList; } if (string.IsNullOrEmpty(options.TaskList) && !string.IsNullOrEmpty(interfaceAttribute?.TaskList)) { options.TaskList = interfaceAttribute.TaskList; } } if (options.StartToCloseTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.StartToCloseTimeoutSeconds > 0) { options.StartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.StartToCloseTimeoutSeconds); } if (options.StartToCloseTimeout <= TimeSpan.Zero) { options.StartToCloseTimeout = client.Settings.WorkflowStartToCloseTimeout; } } if (options.ScheduleToStartTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.ScheduleToStartTimeoutSeconds > 0) { options.ScheduleToStartTimeout = TimeSpan.FromSeconds(methodAttribute.ScheduleToStartTimeoutSeconds); } if (options.ScheduleToStartTimeout <= TimeSpan.Zero) { options.ScheduleToStartTimeout = client.Settings.WorkflowScheduleToStartTimeout; } } if (options.DecisionTaskTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.DecisionTaskTimeoutSeconds > 0) { options.DecisionTaskTimeout = TimeSpan.FromSeconds(methodAttribute.DecisionTaskTimeoutSeconds); } if (options.DecisionTaskTimeout <= TimeSpan.Zero) { options.DecisionTaskTimeout = client.Settings.WorkflowDecisionTaskTimeout; } } if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault) { if (methodAttribute != null && methodAttribute.WorkflowIdReusePolicy != WorkflowIdReusePolicy.UseDefault) { options.WorkflowIdReusePolicy = methodAttribute.WorkflowIdReusePolicy; } if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault) { options.WorkflowIdReusePolicy = client.Settings.WorkflowIdReusePolicy; } } return(options); }
/// <summary> /// Converts the instance into an internal <see cref="InternalStartWorkflowOptions"/>. /// </summary> /// <param name="client">The <see cref="CadenceClient"/>.</param> /// <param name="taskList">Optionally specifies the target task list.</param> /// <param name="methodAttribute">Optionally specifies a <see cref="WorkflowMethodAttribute"/>.</param> /// <returns>The corresponding <see cref="InternalStartWorkflowOptions"/>.</returns> internal InternalStartWorkflowOptions ToInternal(CadenceClient client, string taskList = null, WorkflowMethodAttribute methodAttribute = null) { Covenant.Requires <ArgumentNullException>(client != null); taskList = client.ResolveTaskList(taskList); // Merge optional settings from these options and the method attribute. var decisionTaskStartToCloseTimeout = TimeSpan.FromSeconds(10); var executionStartToCloseTimeout = CadenceClient.DefaultTimeout; var workflowIdReusePolicy = global::Neon.Cadence.WorkflowIdReusePolicy.AllowDuplicateFailedOnly; if (methodAttribute != null) { if (string.IsNullOrEmpty(taskList)) { if (methodAttribute.TaskList != null) { taskList = methodAttribute.TaskList; } else { taskList = client.Settings.DefaultTaskList; } } if (!DecisionTaskStartToCloseTimeout.HasValue && methodAttribute.TaskStartToCloseTimeoutSeconds > 0) { decisionTaskStartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.TaskStartToCloseTimeoutSeconds); } if (!ExecutionStartToCloseTimeout.HasValue && methodAttribute.ExecutionStartToCloseTimeoutSeconds > 0) { executionStartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.ExecutionStartToCloseTimeoutSeconds); } if (!WorkflowIdReusePolicy.HasValue && methodAttribute.WorkflowIdReusePolicy.HasValue) { workflowIdReusePolicy = methodAttribute.WorkflowIdReusePolicy.Value; } } return(new InternalStartWorkflowOptions() { ID = this.WorkflowId, TaskList = taskList, DecisionTaskStartToCloseTimeout = CadenceHelper.ToCadence(decisionTaskStartToCloseTimeout), ExecutionStartToCloseTimeout = CadenceHelper.ToCadence(executionStartToCloseTimeout), RetryPolicy = this.RetryOptions?.ToInternal(), WorkflowIdReusePolicy = (int)workflowIdReusePolicy, CronSchedule = this.CronSchedule, Memo = this.Memo }); }
//--------------------------------------------------------------------- // Static members /// <summary> /// Normalizes the options passed by creating or cloning a new instance as /// required and filling unset properties using default client settings. /// </summary> /// <param name="client">The associated Cadence client.</param> /// <param name="options">The input options or <c>null</c>.</param> /// <param name="workflowInterface">Optionally specifies the workflow interface definition.</param> /// <param name="method">Optionally specifies the target workflow method.</param> /// <returns>The normalized options.</returns> /// <exception cref="ArgumentNullException">Thrown if a valid task list is not specified.</exception> internal static WorkflowOptions Normalize(CadenceClient client, WorkflowOptions options, Type workflowInterface = null, MethodInfo method = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); WorkflowInterfaceAttribute interfaceAttribute = null; WorkflowMethodAttribute methodAttribute = null; if (options == null) { options = new WorkflowOptions(); } else { options = options.Clone(); } if (workflowInterface != null) { CadenceHelper.ValidateWorkflowInterface(workflowInterface); interfaceAttribute = workflowInterface.GetCustomAttribute <WorkflowInterfaceAttribute>(); } if (method != null) { methodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>(); } if (string.IsNullOrEmpty(options.Domain)) { if (!string.IsNullOrEmpty(methodAttribute?.Domain)) { options.Domain = methodAttribute.Domain; } if (string.IsNullOrEmpty(options.Domain) && !string.IsNullOrEmpty(interfaceAttribute?.Domain)) { options.Domain = interfaceAttribute.Domain; } if (string.IsNullOrEmpty(options.Domain)) { options.Domain = client.Settings.DefaultDomain; } if (string.IsNullOrEmpty(options.Domain)) { throw new ArgumentNullException(nameof(options), "You must specify a valid domain explicitly in [CadenceSettings], [ActivityOptions] or via an [ActivityInterface] or [ActivityMethod] attribute on the target activity interface or method."); } } if (string.IsNullOrEmpty(options.TaskList)) { if (!string.IsNullOrEmpty(methodAttribute?.TaskList)) { options.TaskList = methodAttribute.TaskList; } if (string.IsNullOrEmpty(options.TaskList) && !string.IsNullOrEmpty(interfaceAttribute?.TaskList)) { options.TaskList = interfaceAttribute.TaskList; } if (string.IsNullOrEmpty(options.TaskList)) { options.TaskList = client.Settings.DefaultTaskList; } if (string.IsNullOrEmpty(options.TaskList)) { throw new ArgumentNullException(nameof(options), "You must specify a valid task list explicitly via [WorkflowOptions] or using an [WorkflowInterface] or [WorkflowMethod] attribute on the target workflow interface or method."); } } if (options.StartToCloseTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.StartToCloseTimeoutSeconds > 0) { options.StartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.StartToCloseTimeoutSeconds); } if (options.StartToCloseTimeout <= TimeSpan.Zero) { options.StartToCloseTimeout = client.Settings.WorkflowStartToCloseTimeout; } } if (options.ScheduleToStartTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.ScheduleToStartTimeoutSeconds > 0) { options.ScheduleToStartTimeout = TimeSpan.FromSeconds(methodAttribute.ScheduleToStartTimeoutSeconds); } if (options.ScheduleToStartTimeout <= TimeSpan.Zero) { options.ScheduleToStartTimeout = client.Settings.WorkflowScheduleToStartTimeout; } } if (options.DecisionTaskTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.DecisionTaskTimeoutSeconds > 0) { options.DecisionTaskTimeout = TimeSpan.FromSeconds(methodAttribute.DecisionTaskTimeoutSeconds); } if (options.DecisionTaskTimeout <= TimeSpan.Zero) { options.DecisionTaskTimeout = client.Settings.WorkflowDecisionTaskTimeout; } } if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault) { if (methodAttribute != null && methodAttribute.WorkflowIdReusePolicy != WorkflowIdReusePolicy.UseDefault) { options.WorkflowIdReusePolicy = methodAttribute.WorkflowIdReusePolicy; } if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault) { options.WorkflowIdReusePolicy = client.Settings.WorkflowIdReusePolicy; } } if (string.IsNullOrEmpty(options.CronSchedule) && !string.IsNullOrEmpty(methodAttribute?.CronSchedule)) { options.CronSchedule = methodAttribute.CronSchedule; } return(options); }
/// <summary> /// Prepends the Cadence client ID to the workflow type name as well as the optional /// workflow method name to generate the key used to dereference the <see cref="nameToRegistration"/> /// dictionary. /// </summary> /// <param name="client">The Cadence client.</param> /// <param name="workflowTypeName">The workflow type name.</param> /// <param name="workflowMethodAttribute">The workflow method attribute. </param> /// <returns>The workflow registration key.</returns> private static string GetWorkflowTypeKey(CadenceClient client, string workflowTypeName, WorkflowMethodAttribute workflowMethodAttribute) { Covenant.Requires<ArgumentNullException>(client != null, nameof(client)); Covenant.Requires<ArgumentNullException>(!string.IsNullOrEmpty(workflowTypeName), nameof(workflowTypeName)); Covenant.Requires<ArgumentNullException>(workflowMethodAttribute != null, nameof(workflowMethodAttribute)); if (string.IsNullOrEmpty(workflowMethodAttribute.Name)) { return $"{client.ClientId}::{workflowTypeName}"; } else { return $"{client.ClientId}::{workflowTypeName}::{workflowMethodAttribute.Name}"; } }