示例#1
0
        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;
            }
        }
示例#2
0
        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;
            }
        }
示例#3
0
        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;
            }
        }
示例#4
0
        // Responsible for invoking the function, handling the exception, set the output, and if
        // the function execution is out-of-process, handles the replay.
        private async Task InvokeUserCodeAndHandleResults(
            RegisteredFunctionInfo orchestratorInfo,
            OrchestrationContext innerContext)
        {
            try
            {
                Task invokeTask = this.FunctionInvocationCallback();
                if (invokeTask is Task <object> resultTask)
                {
                    // Orchestrator threads cannot perform async I/O, so block on such out-of-proc threads.
                    // Possible performance implications; may need revisiting.
                    object returnValue = orchestratorInfo.IsOutOfProc ? resultTask.Result : await resultTask;
                    if (returnValue != null)
                    {
                        if (orchestratorInfo.IsOutOfProc)
                        {
                            await this.TraceAndReplay(returnValue);
                        }
                        else
                        {
                            this.context.SetOutput(returnValue);
                        }
                    }
                }
                else
                {
                    throw new InvalidOperationException("The WebJobs runtime returned a invocation task that does not support return values!");
                }
            }
            catch (Exception e)
            {
                if (orchestratorInfo != null &&
                    orchestratorInfo.IsOutOfProc &&
                    OutOfProcExceptionHelpers.TryExtractOutOfProcStateJson(e.InnerException, out string returnValue) &&
                    !string.IsNullOrEmpty(returnValue))
                {
                    try
                    {
                        await this.TraceAndReplay(returnValue, e);
                    }
                    catch (OrchestrationFailureException ex)
                    {
                        this.TraceAndSendExceptionNotification(ex.Details);
                        this.context.OrchestrationException = ExceptionDispatchInfo.Capture(ex);
                        throw ex;
                    }
                }
                else
                {
                    this.TraceAndSendExceptionNotification(e.ToString());
                    var orchestrationException = new OrchestrationFailureException(
                        $"Orchestrator function '{this.context.Name}' failed: {e.Message}",
                        Utils.SerializeCause(e, innerContext.ErrorDataConverter));

                    this.context.OrchestrationException =
                        ExceptionDispatchInfo.Capture(orchestrationException);

#if !FUNCTIONS_V1
                    DurableTaskExtension.TagActivityWithOrchestrationStatus(OrchestrationRuntimeStatus.Failed, this.context.InstanceId);
#endif

                    throw orchestrationException;
                }
            }
            finally
            {
                this.context.IsCompleted = true;
            }
        }