private async Task <TResult> CallDurableTaskFunctionAsync <TResult>( string functionName, FunctionType functionType, string instanceId, RetryOptions retryOptions, object input) { this.ThrowIfInvalidAccess(); // TODO: Support for versioning string version = DefaultVersion; this.config.ThrowIfFunctionDoesNotExist(functionName, functionType); Task <TResult> callTask; switch (functionType) { case FunctionType.Activity: System.Diagnostics.Debug.Assert(instanceId == null, "The instanceId parameter should not be used for activity functions."); if (retryOptions == null) { callTask = this.innerContext.ScheduleTask <TResult>(functionName, version, input); } else { callTask = this.innerContext.ScheduleWithRetry <TResult>( functionName, version, retryOptions.GetRetryOptions(), input); } break; case FunctionType.Orchestrator: if (retryOptions == null) { callTask = this.innerContext.CreateSubOrchestrationInstance <TResult>( functionName, version, instanceId, input); } else { callTask = this.innerContext.CreateSubOrchestrationInstanceWithRetry <TResult>( functionName, version, instanceId, retryOptions.GetRetryOptions(), input); } break; default: throw new InvalidOperationException($"Unexpected function type '{functionType}'."); } string sourceFunctionId = this.orchestrationName; this.config.TraceHelper.FunctionScheduled( this.config.Options.HubName, functionName, this.InstanceId, reason: sourceFunctionId, functionType: functionType, isReplay: this.innerContext.IsReplaying); TResult output; Exception exception = null; try { output = await callTask; } catch (TaskFailedException e) { exception = e; string message = string.Format( "The {0} function '{1}' failed: \"{2}\". See the function execution logs for additional details.", functionType.ToString().ToLowerInvariant(), functionName, e.InnerException?.Message); throw new FunctionFailedException(message, e.InnerException); } catch (SubOrchestrationFailedException e) { exception = e; string message = string.Format( "The {0} function '{1}' failed: \"{2}\". See the function execution logs for additional details.", functionType.ToString().ToLowerInvariant(), functionName, e.InnerException?.Message); throw new FunctionFailedException(message, e.InnerException); } catch (Exception e) { exception = e; throw; } finally { if (exception != null && this.innerContext.IsReplaying) { // If this were not a replay, then the activity function trigger would have already // emitted a FunctionFailed trace with the full exception details. this.config.TraceHelper.FunctionFailed( this.config.Options.HubName, functionName, this.InstanceId, reason: $"(replayed {exception.GetType().Name})", functionType: functionType, isReplay: true); } } if (this.innerContext.IsReplaying) { // If this were not a replay, then the activity function trigger would have already // emitted a FunctionCompleted trace with the actual output details. this.config.TraceHelper.FunctionCompleted( this.config.Options.HubName, functionName, this.InstanceId, output: "(replayed)", continuedAsNew: false, functionType: functionType, isReplay: true); } return(output); }
private async Task <TResult> CallDurableTaskFunctionAsync <TResult>(string functionName, FunctionType functionType, RetryOptions retryOptions, object[] parameters) { this.ThrowIfInvalidAccess(); // TODO: Support for versioning string version = DefaultVersion; this.config.ThrowIfInvalidFunctionType(functionName, functionType, version); Task <TResult> callTask; switch (functionType) { case FunctionType.Activity: if (retryOptions == null) { callTask = this.innerContext.ScheduleTask <TResult>(functionName, version, parameters); } else { callTask = this.innerContext.ScheduleWithRetry <TResult>(functionName, version, retryOptions.GetRetryOptions(), parameters); } break; case FunctionType.Orchestrator: if (retryOptions == null) { callTask = this.innerContext.CreateSubOrchestrationInstance <TResult>(functionName, version, JsonConvert.SerializeObject(parameters)); } else { callTask = this.innerContext.CreateSubOrchestrationInstanceWithRetry <TResult>(functionName, version, retryOptions.GetRetryOptions(), JsonConvert.SerializeObject(parameters)); } break; default: throw new InvalidOperationException( string.Format("Unexpected function type '{0}'.", functionType)); } string sourceFunctionId = string.IsNullOrEmpty(this.orchestrationVersion) ? this.orchestrationName : this.orchestrationName + "/" + this.orchestrationVersion; this.config.TraceHelper.FunctionScheduled( this.config.HubName, functionName, version, this.InstanceId, reason: sourceFunctionId, functionType: functionType, isReplay: this.innerContext.IsReplaying); TResult output; try { output = await callTask; } catch (Exception e) { if (this.innerContext.IsReplaying) { // If this were not a replay, then the activity function trigger would have already // emitted a FunctionFailed trace with the full exception details. this.config.TraceHelper.FunctionFailed( this.config.HubName, functionName, version, this.InstanceId, reason: $"(replayed {e.GetType().Name})", functionType: FunctionType.Activity, isReplay: true); } throw; } if (this.innerContext.IsReplaying) { // If this were not a replay, then the activity function trigger would have already // emitted a FunctionCompleted trace with the actual output details. this.config.TraceHelper.FunctionCompleted( this.config.HubName, functionName, version, this.InstanceId, output: "(replayed)", continuedAsNew: false, functionType: FunctionType.Activity, isReplay: true); } return(output); }