public DurableTaskListener( DurableTaskExtension config, string functionId, FunctionName functionName, ITriggeredFunctionExecutor executor, FunctionType functionType, string storageConnectionString) { this.config = config ?? throw new ArgumentNullException(nameof(config)); this.executor = executor ?? throw new ArgumentNullException(nameof(executor)); if (functionName == default(FunctionName)) { throw new ArgumentNullException(nameof(functionName)); } this.functionId = functionId; this.functionName = functionName; this.functionType = functionType; this.storageConnectionString = storageConnectionString; #if !FUNCTIONS_V1 this.scaleMonitor = new Lazy <IScaleMonitor>(() => this.config.GetScaleMonitor( this.functionId, this.functionName, this.storageConnectionString)); #endif }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } ParameterInfo parameter = context.Parameter; OrchestrationTriggerAttribute trigger = parameter.GetCustomAttribute <OrchestrationTriggerAttribute>(inherit: false); if (trigger == null) { return(Task.FromResult <ITriggerBinding>(null)); } // Priority for getting the name is [OrchestrationTrigger], [FunctionName], method name string name = trigger.Orchestration; if (string.IsNullOrEmpty(name)) { MemberInfo method = context.Parameter.Member; name = method.GetCustomAttribute <FunctionNameAttribute>()?.Name ?? method.Name; } // The orchestration name defaults to the method name. var orchestratorName = new FunctionName(name); this.config.RegisterOrchestrator(orchestratorName, null); var binding = new OrchestrationTriggerBinding(this.config, parameter, orchestratorName); return(Task.FromResult <ITriggerBinding>(binding)); }
internal void RegisterOrchestrator(FunctionName orchestratorFunction, ITriggeredFunctionExecutor executor) { if (!this.registeredOrchestrators.TryAdd(orchestratorFunction, executor)) { throw new ArgumentException($"The orchestrator function named '{orchestratorFunction}' is already registered."); } }
private async Task OrchestrationMiddleware(DispatchMiddlewareContext dispatchContext, Func <Task> next) { TaskOrchestrationShim shim = (TaskOrchestrationShim)dispatchContext.GetProperty <TaskOrchestration>(); DurableOrchestrationContext context = shim.Context; OrchestrationRuntimeState orchestrationRuntimeState = dispatchContext.GetProperty <OrchestrationRuntimeState>(); if (orchestrationRuntimeState.ParentInstance != null) { context.ParentInstanceId = orchestrationRuntimeState.ParentInstance.OrchestrationInstance.InstanceId; } context.History = orchestrationRuntimeState.Events; context.SetInput(orchestrationRuntimeState.Input); FunctionName orchestratorFunction = new FunctionName(context.Name); OrchestratorInfo info; if (!this.registeredOrchestrators.TryGetValue(orchestratorFunction, out info)) { string message = this.GetInvalidOrchestratorFunctionMessage(orchestratorFunction.Name); this.TraceHelper.ExtensionWarningEvent( this.Options.HubName, orchestratorFunction.Name, orchestrationRuntimeState.OrchestrationInstance.InstanceId, message); throw new InvalidOperationException(message); } // 1. Start the functions invocation pipeline (billing, logging, bindings, and timeout tracking). FunctionResult result = await info.Executor.TryExecuteAsync( new TriggeredFunctionData { TriggerValue = context, #pragma warning disable CS0618 // Approved for use by this extension InvokeHandler = userCodeInvoker => { // 2. Configure the shim with the inner invoker to execute the user code. shim.SetFunctionInvocationCallback(userCodeInvoker); // 3. Move to the next stage of the DTFx pipeline to trigger the orchestrator shim. return(next()); }, #pragma warning restore CS0618 }, CancellationToken.None); if (!context.IsCompleted) { this.TraceHelper.FunctionAwaited( context.HubName, context.Name, context.InstanceId, context.IsReplaying); } await context.RunDeferredTasks(); }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } ParameterInfo parameter = context.Parameter; ActivityTriggerAttribute trigger = parameter.GetCustomAttribute <ActivityTriggerAttribute>(inherit: false); if (trigger == null) { return(Task.FromResult <ITriggerBinding>(null)); } // Priority for getting the name is [ActivityTrigger], [FunctionName], method name string name = trigger.Activity; if (string.IsNullOrEmpty(name)) { MemberInfo method = context.Parameter.Member; name = method.GetCustomAttribute <FunctionNameAttribute>()?.Name ?? method.Name; } // The activity name defaults to the method name. var activityName = new FunctionName(name, trigger.Version); this.durableTaskConfig.RegisterActivity(activityName, null); var binding = new ActivityTriggerBinding(this, parameter, trigger, activityName); return(Task.FromResult <ITriggerBinding>(binding)); }
internal void RegisterActivity(FunctionName activityFunction, ITriggeredFunctionExecutor executor) { if (!this.registeredActivities.TryAdd(activityFunction, executor)) { throw new ArgumentException($"The activity function named '{activityFunction}' is already registered."); } }
internal OrchestratorInfo GetOrchestratorInfo(FunctionName orchestratorFunction) { OrchestratorInfo info; this.registeredOrchestrators.TryGetValue(orchestratorFunction, out info); return(info); }
internal RegisteredFunctionInfo GetOrchestratorInfo(FunctionName orchestratorFunction) { RegisteredFunctionInfo info; this.knownOrchestrators.TryGetValue(orchestratorFunction, out info); return(info); }
public OrchestrationTriggerBinding( DurableTaskExtension config, ParameterInfo parameterInfo, FunctionName orchestratorName) { this.config = config; this.parameterInfo = parameterInfo; this.orchestratorName = orchestratorName; }
internal void RegisterActivity(FunctionName activityFunction, ITriggeredFunctionExecutor executor) { // Allow adding with a null key and subsequently updating with a non-null key. if (!this.registeredActivities.TryUpdate(activityFunction, executor, null)) { if (!this.registeredActivities.TryAdd(activityFunction, executor)) { throw new ArgumentException($"The activity function named '{activityFunction}' is already registered."); } } }
public ActivityTriggerBinding( ActivityTriggerAttributeBindingProvider parent, ParameterInfo parameterInfo, ActivityTriggerAttribute attribute, FunctionName activity) { this.parent = parent; this.parameterInfo = parameterInfo; this.attribute = attribute; this.activityName = activity; }
internal void AssertOrchestratorExists(string name, string version) { var functionName = new FunctionName(name, version); if (!this.registeredOrchestrators.ContainsKey(functionName)) { throw new ArgumentException( string.Format("The function '{0}' doesn't exist, is disabled, or is not an orchestrator function. The following are the active orchestrator functions: {1}.", functionName, string.Join(", ", this.registeredOrchestrators.Keys))); } }
internal void DeregisterActivity(FunctionName activityFunction) { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: activityFunction.Name, message: $"Deregistering orchestrator function named {activityFunction}.", writeToUserLogs: false); this.registeredActivities.TryRemove(activityFunction, out _); }
internal void RegisterOrchestrator(FunctionName orchestratorFunction, OrchestratorInfo orchestratorInfo) { if (!this.registeredOrchestrators.TryUpdate(orchestratorFunction, orchestratorInfo, null)) { if (!this.registeredOrchestrators.TryAdd(orchestratorFunction, orchestratorInfo)) { throw new ArgumentException( $"The orchestrator function named '{orchestratorFunction}' is already registered."); } } }
TaskActivity INameVersionObjectManager<TaskActivity>.GetObject(string name, string version) { FunctionName activityFunction = new FunctionName(name, version); ITriggeredFunctionExecutor executor; if (!this.registeredActivities.TryGetValue(activityFunction, out executor)) { throw new InvalidOperationException($"Activity function '{activityFunction}' does not exist."); } return new TaskActivityShim(this, executor, name, version); }
public OrchestrationTriggerBinding( DurableTaskExtension config, ParameterInfo parameterInfo, FunctionName orchestratorName, string storageConnectionString) { this.config = config; this.parameterInfo = parameterInfo; this.orchestratorName = orchestratorName; this.storageConnectionString = storageConnectionString; this.BindingDataContract = GetBindingDataContract(parameterInfo); }
public EntityTriggerBinding( DurableTaskExtension config, ParameterInfo parameterInfo, FunctionName entityName, string storageConnectionString) { this.config = config; this.parameterInfo = parameterInfo; this.entityName = entityName; this.storageConnectionString = storageConnectionString; this.BindingDataContract = GetBindingDataContract(parameterInfo); }
internal void ThrowIfFunctionDoesNotExist(string name, FunctionType functionType) { var functionName = new FunctionName(name); if (functionType == FunctionType.Activity && !this.knownActivities.ContainsKey(functionName)) { throw new ArgumentException(this.GetInvalidActivityFunctionMessage(name)); } else if (functionType == FunctionType.Orchestrator && !this.knownOrchestrators.ContainsKey(functionName)) { throw new ArgumentException(this.GetInvalidOrchestratorFunctionMessage(name)); } }
public ActivityTriggerBinding( ActivityTriggerAttributeBindingProvider parent, ParameterInfo parameterInfo, ActivityTriggerAttribute attribute, FunctionName activity, DurableTaskExtension durableTaskConfig) { this.parent = parent; this.parameterInfo = parameterInfo; this.attribute = attribute; this.activityName = activity; this.contract = GetBindingDataContract(parameterInfo); this.durableTaskConfig = durableTaskConfig; }
internal void DeregisterEntity(FunctionName entityFunction) { RegisteredFunctionInfo existing; if (this.knownOrchestrators.TryGetValue(entityFunction, out existing) && !existing.IsDeregistered) { existing.IsDeregistered = true; this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: entityFunction.Name, message: $"Deregistered entity function named {entityFunction}.", writeToUserLogs: false); } }
public DurableTaskScaleMonitor( string functionId, FunctionName functionName, string hubName, string storageConnectionString, EndToEndTraceHelper traceHelper, DisconnectedPerformanceMonitor performanceMonitor = null) { this.functionId = functionId; this.functionName = functionName; this.hubName = hubName; this.storageConnectionString = storageConnectionString; this.performanceMonitor = performanceMonitor; this.traceHelper = traceHelper; this.scaleMonitorDescriptor = new ScaleMonitorDescriptor($"{this.functionId}-DurableTaskTrigger-{this.hubName}".ToLower()); }
internal void DeregisterActivity(FunctionName activityFunction) { RegisteredFunctionInfo info; if (this.knownActivities.TryGetValue(activityFunction, out info) && !info.IsDeregistered) { info.IsDeregistered = true; this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: activityFunction.Name, message: $"Deregistered activity function named {activityFunction}.", writeToUserLogs: false); } }
public DurableTaskListener( DurableTaskExtension config, FunctionName functionName, ITriggeredFunctionExecutor executor, bool isOrchestrator) { this.config = config ?? throw new ArgumentNullException(nameof(config)); this.executor = executor ?? throw new ArgumentNullException(nameof(executor)); if (functionName == default(FunctionName)) { throw new ArgumentNullException(nameof(functionName)); } this.functionName = functionName; this.isOrchestrator = isOrchestrator; }
private async Task OrchestrationMiddleware(DispatchMiddlewareContext dispatchContext, Func <Task> next) { TaskOrchestrationShim shim = (TaskOrchestrationShim)dispatchContext.GetProperty <TaskOrchestration>(); DurableOrchestrationContext context = shim.Context; FunctionName orchestratorFunction = new FunctionName(context.Name, context.Version); ITriggeredFunctionExecutor executor; if (!this.registeredOrchestrators.TryGetValue(orchestratorFunction, out executor)) { throw new InvalidOperationException($"Orchestrator function '{orchestratorFunction}' does not exist."); } // 1. Start the functions invocation pipeline (billing, logging, bindings, and timeout tracking). FunctionResult result = await executor.TryExecuteAsync( new TriggeredFunctionData { TriggerValue = context, #pragma warning disable CS0618 // Approved for use by this extension InvokeHandler = userCodeInvoker => { // 2. Configure the shim with the inner invoker to execute the user code. shim.SetFunctionInvocationCallback(userCodeInvoker); // 3. Move to the next stage of the DTFx pipeline to trigger the orchestrator shim. return(next()); }, #pragma warning restore CS0618 }, CancellationToken.None); if (!context.IsCompleted) { this.TraceHelper.FunctionAwaited( context.HubName, context.Name, context.Version, context.InstanceId, context.IsReplaying); } await context.RunDeferredTasks(); }
internal void RegisterActivity(FunctionName activityFunction, ITriggeredFunctionExecutor executor) { // Allow adding with a null key and subsequently updating with a non-null key. if (!this.registeredActivities.TryUpdate(activityFunction, executor, null)) { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: activityFunction.Name, message: $"Registering orchestrator function named {activityFunction}.", writeToUserLogs: false); if (!this.registeredActivities.TryAdd(activityFunction, executor)) { throw new ArgumentException($"The activity function named '{activityFunction}' is already registered."); } } }
internal void RegisterOrchestrator(FunctionName orchestratorFunction, OrchestratorInfo orchestratorInfo) { if (!this.registeredOrchestrators.TryUpdate(orchestratorFunction, orchestratorInfo, null)) { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: orchestratorFunction.Name, message: $"Registering orchestrator function named {orchestratorFunction}.", writeToUserLogs: false); if (!this.registeredOrchestrators.TryAdd(orchestratorFunction, orchestratorInfo)) { throw new ArgumentException( $"The orchestrator function named '{orchestratorFunction}' is already registered."); } } }
/// <summary> /// Called by the Durable Task Framework: Returns the specified <see cref="TaskActivity"/>. /// </summary> /// <param name="name">The name of the activity to return.</param> /// <param name="version">Not used.</param> /// <returns>An activity shim that delegates execution to an activity function.</returns> TaskActivity INameVersionObjectManager <TaskActivity> .GetObject(string name, string version) { FunctionName activityFunction = new FunctionName(name); RegisteredFunctionInfo info; if (!this.knownActivities.TryGetValue(activityFunction, out info)) { string message = $"Activity function '{activityFunction}' does not exist."; this.TraceHelper.ExtensionWarningEvent( this.Options.HubName, activityFunction.Name, string.Empty /* TODO: Flow the instance id into this event */, message); throw new InvalidOperationException(message); } return(new TaskActivityShim(this, info.Executor, name)); }
internal void RegisterActivity(FunctionName activityFunction, ITriggeredFunctionExecutor executor) { if (this.knownActivities.TryGetValue(activityFunction, out RegisteredFunctionInfo existing)) { existing.Executor = executor; } else { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: activityFunction.Name, message: $"Registering activity function named {activityFunction}.", writeToUserLogs: false); var info = new RegisteredFunctionInfo(executor, isOutOfProc: false); this.knownActivities[activityFunction] = info; } }
internal void RegisterOrchestrator(FunctionName orchestratorFunction, RegisteredFunctionInfo orchestratorInfo) { if (orchestratorInfo != null) { orchestratorInfo.IsDeregistered = false; } if (this.knownOrchestrators.TryAdd(orchestratorFunction, orchestratorInfo)) { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: orchestratorFunction.Name, message: $"Registered orchestrator function named {orchestratorFunction}.", writeToUserLogs: false); } else { this.knownOrchestrators[orchestratorFunction] = orchestratorInfo; } }
internal void RegisterEntity(FunctionName entityFunction, RegisteredFunctionInfo entityInfo) { if (entityInfo != null) { entityInfo.IsDeregistered = false; } if (this.knownEntities.TryAdd(entityFunction, entityInfo)) { this.TraceHelper.ExtensionInformationalEvent( this.Options.HubName, instanceId: string.Empty, functionName: entityFunction.Name, message: $"Registered entity function named {entityFunction}.", writeToUserLogs: false); } else { this.knownEntities[entityFunction] = entityInfo; } }