Skip to content

Commit

Permalink
fix(NetworkingModule): Adds timeout behavior to NetworkingModule
Browse files Browse the repository at this point in the history
Timeout is now wired up using a cancellation token (no native behavior for timeout in the HttpClient).

Fixes microsoft#382
  • Loading branch information
rozele authored and GantMan committed Sep 29, 2016
1 parent af291de commit dd25be8
Showing 1 changed file with 56 additions and 35 deletions.
91 changes: 56 additions & 35 deletions ReactNative/Modules/Network/NetworkingModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void sendRequest(
{
if (headerData.ContentType == null)
{
OnRequestError(requestId, "Payload is set but no 'content-type' header specified.");
OnRequestError(requestId, "Payload is set but no 'content-type' header specified.", false);
return;
}

Expand All @@ -124,14 +124,16 @@ public void sendRequest(
}
else if ((formData = data.Value<JArray>("formData")) != null)
{
// TODO: (#388) Add support for form data.
throw new NotImplementedException("HTTP handling for FormData not yet implemented.");
}
}

_tasks.Add(requestId, token => ProcessRequestAsync(
requestId,
useIncrementalUpdates,
request,
requestId,
useIncrementalUpdates,
timeout,
request,
token));
}

Expand All @@ -154,53 +156,71 @@ public override void OnReactInstanceDispose()
}

private async Task ProcessRequestAsync(
int requestId,
bool useIncrementalUpdates,
int requestId,
bool useIncrementalUpdates,
int timeout,
HttpRequestMessage request,
CancellationToken token)
{
try
var timeoutSource = timeout > 0
? new CancellationTokenSource(timeout)
: new CancellationTokenSource();

using (timeoutSource)
{
using (var response = await _client.SendRequestAsync(request, token))
try
{
OnResponseReceived(requestId, response);

if (useIncrementalUpdates)
using (token.Register(timeoutSource.Cancel))
using (var response = await _client.SendRequestAsync(request, timeoutSource.Token))
{
using (var inputStream = await response.Content.ReadAsInputStreamAsync())
using (var stream = inputStream.AsStreamForRead())
OnResponseReceived(requestId, response);

if (useIncrementalUpdates)
{
await ProcessResponseIncrementalAsync(requestId, stream, token);
OnRequestSuccess(requestId);
using (var inputStream = await response.Content.ReadAsInputStreamAsync())
using (var stream = inputStream.AsStreamForRead())
{
await ProcessResponseIncrementalAsync(requestId, stream, timeoutSource.Token);
OnRequestSuccess(requestId);
}
}
}
else
{
if (response.Content != null)
else
{
var responseBody = await response.Content.ReadAsStringAsync();
if (responseBody != null)
if (response.Content != null)
{
OnDataReceived(requestId, responseBody);
var responseBody = await response.Content.ReadAsStringAsync();
if (responseBody != null)
{
OnDataReceived(requestId, responseBody);
}
}
}

OnRequestSuccess(requestId);
OnRequestSuccess(requestId);
}
}
}
}
catch (Exception ex)
{
if (_shuttingDown)
catch (OperationCanceledException ex)
when (ex.CancellationToken == timeoutSource.Token)
{
return;
// Cancellation was due to timeout
if (!token.IsCancellationRequested)
{
OnRequestError(requestId, ex.Message, true);
}
}
catch (Exception ex)
{
if (_shuttingDown)
{
return;
}

OnRequestError(requestId, ex.Message);
}
finally
{
request.Dispose();
OnRequestError(requestId, ex.Message, false);
}
finally
{
request.Dispose();
}
}
}

Expand Down Expand Up @@ -264,12 +284,13 @@ private void OnDataReceived(int requestId, string responseBody)
});
}

private void OnRequestError(int requestId, string message)
private void OnRequestError(int requestId, string message, bool timeout)
{
EventEmitter.emit("didCompleteNetworkResponse", new JArray
{
requestId,
message,
timeout
});
}

Expand Down

0 comments on commit dd25be8

Please sign in to comment.