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

retry when the request times out #3420

Merged
merged 2 commits into from
Nov 13, 2018
Merged
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
35 changes: 24 additions & 11 deletions src/Paket.Core/Common/NetUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -566,19 +566,30 @@ let rec private _safeGetFromUrl (auth:Auth option, url : string, contentType : s
let rec getExceptionNames (exn:Exception) = [
if exn <> null then
yield exn.GetType().Name
if exn.InnerException <> null then
yield! getExceptionNames exn.InnerException
match exn with
| :? System.AggregateException as agg ->
for ei in agg.InnerExceptions do
yield! getExceptionNames ei
| _ when exn.InnerException <> null ->
yield! getExceptionNames exn.InnerException
| _ -> ()
]

let shouldRetry exn = isMonoRuntime && iTry < nTries && (getExceptionNames exn |> List.contains "MonoBtlsException")
use timeoutTok = new System.Threading.CancellationTokenSource()
timeoutTok.CancelAfter(60000)
let shouldRetry () =
iTry < nTries
let shouldRetryTimeout exn =
let exnNames = getExceptionNames exn
shouldRetry () &&
(timeoutTok.IsCancellationRequested && (exnNames |> List.contains "OperationCanceledException" ))

async {
try
let uri = Uri url
use client = createHttpClient (url,auth)
let! tok = Async.CancellationToken
let tokSource = System.Threading.CancellationTokenSource.CreateLinkedTokenSource(tok)
tokSource.CancelAfter(60000)
let tokSource = System.Threading.CancellationTokenSource.CreateLinkedTokenSource(tok, timeoutTok.Token)

if notNullOrEmpty contentType then
addAcceptHeader client contentType
Expand All @@ -589,13 +600,15 @@ let rec private _safeGetFromUrl (auth:Auth option, url : string, contentType : s
let! raw = client.DownloadStringTaskAsync(uri, tokSource.Token) |> Async.AwaitTaskWithoutAggregate
return SuccessResponse raw
with

| exn when shouldRetry exn ->
raise (Exception("Hello from _safeGetFromUrl.shouldRetry", exn))
// there are issues with mono, try again :\
Logging.traceWarnfn "Request failed, this is likely due to a mono issue. Trying again, this was try %i/%i" iTry nTries
| exn when shouldRetryTimeout exn ->
Logging.traceWarnfn "Request to '%s' didn't respond after 60 seconds, trying again %i/%i" url iTry nTries
return! _safeGetFromUrl(auth, url, contentType, iTry + 1, nTries)

| :? HttpRequestException as req when (shouldRetry () && (req.InnerException :? System.Net.Sockets.SocketException)) ->
Logging.traceWarnfn "Request to '%s' failed with '%s', trying again %i/%i" url req.Message iTry nTries
return! _safeGetFromUrl(auth, url, contentType, iTry + 1, nTries)
| :? OperationCanceledException as cancel when timeoutTok.IsCancellationRequested ->
let msg = sprintf "Request to '%s' finally timed out after 60 seconds after several retries" url
return raise (Exception(msg, cancel))
| :? RequestFailedException as w ->
match w.Info with
| Some { StatusCode = HttpStatusCode.NotFound } -> return NotFound
Expand Down