/// <summary> /// Raises the <see cref="ActivityExecuteEvent"/>. /// </summary> /// <param name="options">The activity options.</param> internal void RaiseActivityExecuteEvent(ActivityOptions options) { ActivityExecuteEvent?.Invoke(this, options); }
//--------------------------------------------------------------------- // 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 Temporal client.</param> /// <param name="options">The input options or <c>null</c>.</param> /// <param name="activityInterface">Optionally specifies the activity 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 queue is not specified.</exception> internal static ActivityOptions Normalize(TemporalClient client, ActivityOptions options, Type activityInterface = null, MethodInfo method = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); options = options ?? new ActivityOptions(); ActivityInterfaceAttribute interfaceAttribute = null; ActivityMethodAttribute methodAttribute = null; if (activityInterface != null) { TemporalHelper.ValidateActivityInterface(activityInterface); interfaceAttribute = activityInterface.GetCustomAttribute <ActivityInterfaceAttribute>(); } if (method != null) { methodAttribute = method.GetCustomAttribute <ActivityMethodAttribute>(); } if (string.IsNullOrEmpty(options.Namespace)) { if (!string.IsNullOrEmpty(methodAttribute?.Namespace)) { options.Namespace = methodAttribute.Namespace; } if (string.IsNullOrEmpty(options.Namespace) && !string.IsNullOrEmpty(interfaceAttribute?.Namespace)) { options.Namespace = interfaceAttribute.Namespace; } } if (string.IsNullOrEmpty(options.TaskQueue)) { if (!string.IsNullOrEmpty(methodAttribute?.TaskQueue)) { options.TaskQueue = methodAttribute.TaskQueue; } if (string.IsNullOrEmpty(options.TaskQueue) && !string.IsNullOrEmpty(interfaceAttribute?.TaskQueue)) { options.TaskQueue = interfaceAttribute.TaskQueue; } } if (options.ScheduleToCloseTimeout <= TimeSpan.Zero) { if (methodAttribute != null && methodAttribute.ScheduleToCloseTimeoutSeconds > 0) { options.ScheduleToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.ScheduleToCloseTimeoutSeconds); } if (options.ScheduleToCloseTimeout <= TimeSpan.Zero) { options.ScheduleToCloseTimeout = client.Settings.ActivityScheduleToCloseTimeout; } } 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.ActivityScheduleToStartTimeout; } } 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.ActivityStartToCloseTimeout; } } return(options); }
/// <summary> /// Internal constructor. /// </summary> /// <param name="parentWorkflow">The associated parent workflow.</param> /// <param name="activityTypeName"> /// Specifies the target activity type name. /// </param> /// <param name="options">The activity options or <c>null</c>.</param> internal ActivityFutureStub(Workflow parentWorkflow, string activityTypeName, ActivityOptions options = null) { Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(activityTypeName), nameof(activityTypeName)); this.parentWorkflow = parentWorkflow; this.client = parentWorkflow.Client; this.activityTypeName = activityTypeName; this.hasStarted = false; this.options = ActivityOptions.Normalize(client, options); }
/// <summary> /// Internal constructor. /// </summary> /// <param name="parentWorkflow">The associated parent workflow.</param> /// <param name="methodName"> /// Optionally identifies the target activity method by the name specified in /// the <c>[ActivityMethod]</c> attribute tagging the method. Pass a <c>null</c> /// or empty string to target the default method. /// </param> /// <param name="options">The activity options or <c>null</c>.</param> internal ActivityFutureStub(Workflow parentWorkflow, string methodName = null, ActivityOptions options = null) { Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow)); var activityInterface = typeof(TActivityInterface); TemporalHelper.ValidateActivityInterface(activityInterface); this.parentWorkflow = parentWorkflow; this.client = parentWorkflow.Client; this.hasStarted = false; var activityTarget = TemporalHelper.GetActivityTarget(activityInterface, methodName); var methodAttribute = activityTarget.MethodAttribute; this.activityTypeName = activityTarget.ActivityTypeName; this.targetMethod = activityTarget.TargetMethod; this.options = ActivityOptions.Normalize(client, options, typeof(TActivityInterface), activityTarget.TargetMethod); }
/// <summary> /// Internal constructor. /// </summary> /// <param name="client">The associated client.</param> /// <param name="parentWorkflow">Identifies the parent workflow.</param> /// <param name="activityTypeName">Specifies the target activity type name.</param> /// <param name="options">Optionally specifies custom activity options.</param> /// <remarks> /// <para> /// <paramref name="activityTypeName"/> specifies the target activity implementation type name and optionally, /// the specific activity method to be called for activity interfaces that have multiple methods. For /// activity methods tagged by <c>ActivityMethod]</c>[ with specifying a name, the activity type name will default /// to the fully qualified interface type name or the custom type name specified by <see cref="ActivityAttribute.Name"/>. /// </para> /// <para> /// For activity methods with <see cref="ActivityMethodAttribute.Name"/> specified, the activity type will /// look like this by default: /// </para> /// <code> /// ACTIVITY-TYPE-NAME::METHOD-NAME /// </code> /// <note> /// You may need to customize activity type name when interoperating with activities written /// in other languages. See <a href="https://doc.neonkube.com/Neon.Temporal-CrossPlatform.htm">Temporal Cross-Platform</a> /// for more information. /// </note> /// </remarks> internal ActivityStub(TemporalClient client, Workflow parentWorkflow, string activityTypeName, ActivityOptions options = null) { Covenant.Requires <ArgumentNullException>(client != null, nameof(client)); Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow)); Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(activityTypeName), nameof(activityTypeName)); this.client = client; this.parentWorkflow = parentWorkflow; this.activityTypeName = activityTypeName; this.options = options; }