diff --git a/NOnion/NOnion.fsproj b/NOnion/NOnion.fsproj index b7a72d39..e3e280ef 100644 --- a/NOnion/NOnion.fsproj +++ b/NOnion/NOnion.fsproj @@ -86,6 +86,7 @@ + diff --git a/NOnion/Network/TorGuard.fs b/NOnion/Network/TorGuard.fs index d32e9584..5c1109cc 100644 --- a/NOnion/Network/TorGuard.fs +++ b/NOnion/Network/TorGuard.fs @@ -9,6 +9,8 @@ open System.Security.Authentication open System.Security.Cryptography open System.Threading +open Fsdk + open NOnion open NOnion.Cells open NOnion.Utility diff --git a/NOnion/Services/TorServiceHost.fs b/NOnion/Services/TorServiceHost.fs index 5d31649e..a36cba24 100644 --- a/NOnion/Services/TorServiceHost.fs +++ b/NOnion/Services/TorServiceHost.fs @@ -15,6 +15,7 @@ open Org.BouncyCastle.Crypto.Parameters open Org.BouncyCastle.Crypto.Generators open Org.BouncyCastle.Crypto.Signers open Org.BouncyCastle.Security +open Fsdk open NOnion open NOnion.Cells.Relay diff --git a/NOnion/Utility/FSharpUtil.fs b/NOnion/Utility/FSharpUtil.fs index 24aeb741..b5002f00 100644 --- a/NOnion/Utility/FSharpUtil.fs +++ b/NOnion/Utility/FSharpUtil.fs @@ -4,93 +4,41 @@ open System open System.Runtime.ExceptionServices open FSharpx.Collections +open Fsdk open NOnion module FSharpUtil = - //Implementation copied from https://github.com/nblockchain/geewallet/blob/master/src/GWallet.Backend/FSharpUtil.fs - let ReRaise(ex: Exception) : Exception = - (ExceptionDispatchInfo.Capture ex).Throw() - failwith "Should be unreachable" - ex - - let rec public FindException<'T when 'T :> Exception> - (ex: Exception) - : Option<'T> = - let rec findExInSeq(sq: seq) = - match Seq.tryHeadTail sq with - | Some(head, tail) -> - match FindException head with - | Some ex -> Some ex - | None -> findExInSeq <| tail - | None -> None - - if isNull ex then - None - else - match ex with - | :? 'T as specificEx -> Some specificEx - | :? AggregateException as aggEx -> - findExInSeq aggEx.InnerExceptions - | _ -> FindException<'T> ex.InnerException - - type private Either<'Val, 'Err when 'Err :> Exception> = - | FailureResult of 'Err - | SuccessfulValue of 'Val - let WithTimeout (timeSpan: TimeSpan) (job: Async<'R>) : Async<'R> = async { - let read = - async { - let! value = job - return value |> SuccessfulValue |> Some - } - - let delay = - async { - let total = int timeSpan.TotalMilliseconds - do! Async.Sleep total - return FailureResult <| TimeoutException() |> Some - } - - let! dummyOption = Async.Choice([ read; delay ]) + let! result = FSharpUtil.WithTimeout timeSpan job - match dummyOption with - | Some theResult -> - match theResult with - | SuccessfulValue r -> return r - | FailureResult _ -> return raise <| TimeoutErrorException() - | None -> - // none of the jobs passed to Async.Choice returns None - return failwith "unreachable" + match result with + | Some value -> return value + | None -> return raise <| TimeoutErrorException() } let Retry<'TEx when 'TEx :> Exception> (jobToRetry: Async) (maxRetryCount: int) = - let rec retryLoop(tryNumber: int) = - async { - try - do! jobToRetry - with - | :? 'TEx as ex -> - if tryNumber < maxRetryCount then - return! retryLoop(tryNumber + 1) - else - sprintf - "Maximum retry count reached, ex = %s" - (ex.ToString()) - |> TorLogger.Log - - return raise <| ReRaise ex - | ex -> - sprintf - "Unexpected exception happened in the retry loop, ex = %s" - (ex.ToString()) - |> TorLogger.Log - - return raise <| ReRaise ex - } - - retryLoop 0 + async { + try + do! + FSharpUtil.Retry<_, 'TEx> + (fun () -> jobToRetry) + maxRetryCount + with + | :? 'TEx as ex -> + sprintf "Maximum retry count reached, ex = %s" (ex.ToString()) + |> TorLogger.Log + + return raise <| FSharpUtil.ReRaise ex + | ex -> + sprintf + "Unexpected exception happened in the retry loop, ex = %s" + (ex.ToString()) + |> TorLogger.Log + + return raise <| FSharpUtil.ReRaise ex + } diff --git a/NOnion/Utility/MailboxUtil.fs b/NOnion/Utility/MailboxUtil.fs index 6024f954..515fbb4a 100644 --- a/NOnion/Utility/MailboxUtil.fs +++ b/NOnion/Utility/MailboxUtil.fs @@ -2,6 +2,8 @@ open System.Net.Sockets +open Fsdk + open NOnion module internal MailboxResultUtil = diff --git a/NOnion/Utility/ResultUtil.fs b/NOnion/Utility/ResultUtil.fs index e997ec7c..28dcfe7b 100644 --- a/NOnion/Utility/ResultUtil.fs +++ b/NOnion/Utility/ResultUtil.fs @@ -1,5 +1,7 @@ namespace NOnion.Utility +open Fsdk + //FIXME: for some reason FSharpUtil is in NOnion namespace instead of NOnion.Utility open NOnion