Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated WaitForCompletionOrCreateCheckStatusResponseAsync API #1572

Merged
merged 4 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,19 @@ HttpManagementPayload IDurableOrchestrationClient.CreateHttpManagementPayload(st
}

/// <inheritdoc />
async Task<HttpResponseMessage> IDurableOrchestrationClient.WaitForCompletionOrCreateCheckStatusResponseAsync(HttpRequestMessage request, string instanceId, TimeSpan? timeout, TimeSpan? retryInterval)
async Task<HttpResponseMessage> IDurableOrchestrationClient.WaitForCompletionOrCreateCheckStatusResponseAsync(HttpRequestMessage request, string instanceId, TimeSpan? timeout, TimeSpan? retryInterval, bool returnInternalServerErrorOnFailure)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to document this as a breaking change for customers. I don't anticipate it will bother many customers, since they can just add a It.IsAny<bool>() to their setup in their mocked function call.

{
return await this.WaitForCompletionOrCreateCheckStatusResponseAsync(
request,
instanceId,
this.attribute,
timeout ?? TimeSpan.FromSeconds(10),
retryInterval ?? TimeSpan.FromSeconds(1));
retryInterval ?? TimeSpan.FromSeconds(1),
returnInternalServerErrorOnFailure);
}

/// <inheritdoc />
async Task<IActionResult> IDurableOrchestrationClient.WaitForCompletionOrCreateCheckStatusResponseAsync(HttpRequest request, string instanceId, TimeSpan? timeout, TimeSpan? retryInterval)
async Task<IActionResult> IDurableOrchestrationClient.WaitForCompletionOrCreateCheckStatusResponseAsync(HttpRequest request, string instanceId, TimeSpan? timeout, TimeSpan? retryInterval, bool returnInternalServerErrorOnFailure)
{
HttpRequestMessage requestMessage = ConvertHttpRequestMessage(request);
HttpResponseMessage responseMessage = await ((IDurableOrchestrationClient)this).WaitForCompletionOrCreateCheckStatusResponseAsync(requestMessage, instanceId, timeout, retryInterval);
Expand Down Expand Up @@ -661,14 +662,16 @@ internal async Task<HttpResponseMessage> WaitForCompletionOrCreateCheckStatusRes
string instanceId,
DurableClientAttribute attribute,
TimeSpan timeout,
TimeSpan retryInterval)
TimeSpan retryInterval,
bool returnInternalServerErrorOnFailure)
{
return await this.httpApiHandler.WaitForCompletionOrCreateCheckStatusResponseAsync(
request,
instanceId,
attribute,
timeout,
retryInterval);
retryInterval,
returnInternalServerErrorOnFailure);
}

private static bool IsOrchestrationRunning(OrchestrationState status)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,16 @@ public interface IDurableOrchestrationClient
/// <param name="instanceId">The unique ID of the instance to check.</param>
/// <param name="timeout">Total allowed timeout for output from the durable function. The default value is 10 seconds.</param>
/// <param name="retryInterval">The timeout between checks for output from the durable function. The default value is 1 second.</param>
/// <param name="returnInternalServerErrorOnFailure">Optional parameter that configures the http response code returned. Defaults to <c>false</c>.
/// If <c>true</c>, the returned http response code will be a 500 when the orchestrator is in a failed state, when <c>false</c> it will
/// return 200.</param>
/// <returns>An HTTP response which may include a 202 and location header or a 200 with the durable function output in the response body.</returns>
Task<HttpResponseMessage> WaitForCompletionOrCreateCheckStatusResponseAsync(
HttpRequestMessage request,
string instanceId,
TimeSpan? timeout = null,
TimeSpan? retryInterval = null);
TimeSpan? retryInterval = null,
bool returnInternalServerErrorOnFailure = false);

/// <summary>
/// Creates an HTTP response which either contains a payload of management URLs for a non-completed instance
Expand All @@ -99,12 +103,16 @@ Task<HttpResponseMessage> WaitForCompletionOrCreateCheckStatusResponseAsync(
/// <param name="instanceId">The unique ID of the instance to check.</param>
/// <param name="timeout">Total allowed timeout for output from the durable function. The default value is 10 seconds.</param>
/// <param name="retryInterval">The timeout between checks for output from the durable function. The default value is 1 second.</param>
/// <param name="returnInternalServerErrorOnFailure">Optional parameter that configures the http response code returned. Defaults to <c>false</c>.
/// If <c>true</c>, the returned http response code will be a 500 when the orchestrator is in a failed state, when <c>false</c> it will
/// return 200.</param>
/// <returns>An HTTP response which may include a 202 and location header or a 200 with the durable function output in the response body.</returns>
Task<IActionResult> WaitForCompletionOrCreateCheckStatusResponseAsync(
HttpRequest request,
string instanceId,
TimeSpan? timeout = null,
TimeSpan? retryInterval = null);
TimeSpan? retryInterval = null,
bool returnInternalServerErrorOnFailure = false);

/// <summary>
/// Starts a new execution of the specified orchestrator function.
Expand Down
24 changes: 17 additions & 7 deletions src/WebJobs.Extensions.DurableTask/HttpApiHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,15 @@ internal async Task<HttpResponseMessage> WaitForCompletionOrCreateCheckStatusRes
string instanceId,
DurableClientAttribute attribute,
TimeSpan timeout,
TimeSpan retryInterval)
TimeSpan retryInterval,
bool returnInternalServerErrorOnFailure = false)
{
if (retryInterval > timeout)
{
throw new ArgumentException($"Total timeout {timeout.TotalSeconds} should be bigger than retry timeout {retryInterval.TotalSeconds}");
}

HttpManagementPayload httpManagementPayload = this.GetClientResponseLinks(request, instanceId, attribute?.TaskHub, attribute?.ConnectionName);
HttpManagementPayload httpManagementPayload = this.GetClientResponseLinks(request, instanceId, attribute?.TaskHub, attribute?.ConnectionName, returnInternalServerErrorOnFailure);

IDurableOrchestrationClient client = this.GetClient(request);
Stopwatch stopwatch = Stopwatch.StartNew();
Expand All @@ -195,7 +196,7 @@ internal async Task<HttpResponseMessage> WaitForCompletionOrCreateCheckStatusRes
status.RuntimeStatus == OrchestrationRuntimeStatus.Failed ||
status.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
{
return await this.HandleGetStatusRequestAsync(request, instanceId);
return await this.HandleGetStatusRequestAsync(request, instanceId, returnInternalServerErrorOnFailure);
}
}
ConnorMcMahon marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -518,7 +519,8 @@ private async Task<HttpResponseMessage> HandleDeleteHistoryWithFiltersRequestAsy

private async Task<HttpResponseMessage> HandleGetStatusRequestAsync(
HttpRequestMessage request,
string instanceId)
string instanceId,
bool? returnInternalServerErrorOnFailure = null)
{
IDurableOrchestrationClient client = this.GetClient(request);
var queryNameValuePairs = request.GetQueryNameValuePairs();
Expand All @@ -538,9 +540,17 @@ private async Task<HttpResponseMessage> HandleGetStatusRequestAsync(
showInput = true;
}

if (!TryGetBooleanQueryParameterValue(queryNameValuePairs, ReturnInternalServerErrorOnFailure, out bool returnInternalServerErrorOnFailure))
bool finalReturnInternalServerErrorOnFailure;
if (returnInternalServerErrorOnFailure.HasValue)
{
returnInternalServerErrorOnFailure = false;
finalReturnInternalServerErrorOnFailure = returnInternalServerErrorOnFailure.Value;
}
else
{
if (!TryGetBooleanQueryParameterValue(queryNameValuePairs, ReturnInternalServerErrorOnFailure, out finalReturnInternalServerErrorOnFailure))
{
finalReturnInternalServerErrorOnFailure = false;
}
}

var status = await client.GetStatusAsync(instanceId, showHistory, showHistoryOutput, showInput);
Expand All @@ -564,7 +574,7 @@ private async Task<HttpResponseMessage> HandleGetStatusRequestAsync(

// The orchestration has failed - return 500 w/out Location header
case OrchestrationRuntimeStatus.Failed:
statusCode = returnInternalServerErrorOnFailure ? HttpStatusCode.InternalServerError : HttpStatusCode.OK;
statusCode = finalReturnInternalServerErrorOnFailure ? HttpStatusCode.InternalServerError : HttpStatusCode.OK;
location = null;
break;

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading