diff --git a/NOnion/NOnion.fsproj b/NOnion/NOnion.fsproj index 50428413..75278f37 100644 --- a/NOnion/NOnion.fsproj +++ b/NOnion/NOnion.fsproj @@ -91,6 +91,7 @@ + diff --git a/NOnion/Network/TorGuard.fs b/NOnion/Network/TorGuard.fs index 8450be42..46248673 100644 --- a/NOnion/Network/TorGuard.fs +++ b/NOnion/Network/TorGuard.fs @@ -11,6 +11,7 @@ open System.Threading open Org.BouncyCastle.Security open Org.BouncyCastle.X509 +open Fsdk open NOnion open NOnion.Cells diff --git a/NOnion/Services/TorServiceHost.fs b/NOnion/Services/TorServiceHost.fs index daf8c6fc..989019b1 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 6cf7d801..6c556a28 100644 --- a/NOnion/Utility/FSharpUtil.fs +++ b/NOnion/Utility/FSharpUtil.fs @@ -4,96 +4,44 @@ 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 + } let UnwrapOption<'T> (opt: Option<'T>) (msg: string) : 'T = match opt with 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