@@ -4,93 +4,41 @@ open System
4
4
open System.Runtime .ExceptionServices
5
5
6
6
open FSharpx.Collections
7
+ open Fsdk
7
8
8
9
open NOnion
9
10
10
11
module FSharpUtil =
11
- //Implementation copied from https://github.com/nblockchain/geewallet/blob/master/src/GWallet.Backend/FSharpUtil.fs
12
- let ReRaise ( ex : Exception ) : Exception =
13
- ( ExceptionDispatchInfo.Capture ex) .Throw()
14
- failwith " Should be unreachable"
15
- ex
16
-
17
- let rec public FindException < 'T when 'T :> Exception >
18
- ( ex : Exception )
19
- : Option < 'T > =
20
- let rec findExInSeq ( sq : seq < Exception >) =
21
- match Seq.tryHeadTail sq with
22
- | Some( head, tail) ->
23
- match FindException head with
24
- | Some ex -> Some ex
25
- | None -> findExInSeq <| tail
26
- | None -> None
27
-
28
- if isNull ex then
29
- None
30
- else
31
- match ex with
32
- | :? 'T as specificEx -> Some specificEx
33
- | :? AggregateException as aggEx ->
34
- findExInSeq aggEx.InnerExceptions
35
- | _ -> FindException< 'T> ex.InnerException
36
-
37
- type private Either < 'Val , 'Err when 'Err :> Exception > =
38
- | FailureResult of 'Err
39
- | SuccessfulValue of 'Val
40
-
41
12
let WithTimeout ( timeSpan : TimeSpan ) ( job : Async < 'R >) : Async < 'R > =
42
13
async {
43
- let read =
44
- async {
45
- let! value = job
46
- return value |> SuccessfulValue |> Some
47
- }
48
-
49
- let delay =
50
- async {
51
- let total = int timeSpan.TotalMilliseconds
52
- do ! Async.Sleep total
53
- return FailureResult <| TimeoutException() |> Some
54
- }
55
-
56
- let! dummyOption = Async.Choice([ read; delay ])
14
+ let! result = FSharpUtil.WithTimeout timeSpan job
57
15
58
- match dummyOption with
59
- | Some theResult ->
60
- match theResult with
61
- | SuccessfulValue r -> return r
62
- | FailureResult _ -> return raise <| TimeoutErrorException()
63
- | None ->
64
- // none of the jobs passed to Async.Choice returns None
65
- return failwith " unreachable"
16
+ match result with
17
+ | Some value -> return value
18
+ | None -> return raise <| TimeoutErrorException()
66
19
}
67
20
68
21
let Retry < 'TEx when 'TEx :> Exception >
69
22
( jobToRetry : Async < unit >)
70
23
( maxRetryCount : int )
71
24
=
72
- let rec retryLoop ( tryNumber : int ) =
73
- async {
74
- try
75
- do ! jobToRetry
76
- with
77
- | : ? 'TEx as ex ->
78
- if tryNumber < maxRetryCount then
79
- return ! retryLoop( tryNumber + 1 )
80
- else
81
- sprintf
82
- " Maximum retry count reached, ex = %s "
83
- ( ex.ToString())
84
- |> TorLogger.Log
85
-
86
- return raise <| ReRaise ex
87
- | ex ->
88
- sprintf
89
- " Unexpected exception happened in the retry loop, ex = %s "
90
- ( ex.ToString())
91
- |> TorLogger.Log
92
-
93
- return raise <| ReRaise ex
94
- }
95
-
96
- retryLoop 0
25
+ async {
26
+ try
27
+ do !
28
+ FSharpUtil.Retry<_, 'TEx>
29
+ ( fun () -> jobToRetry)
30
+ maxRetryCount
31
+ with
32
+ | : ? 'TEx as ex ->
33
+ sprintf " Maximum retry count reached, ex = %s " ( ex.ToString())
34
+ |> TorLogger.Log
35
+
36
+ return raise <| FSharpUtil.ReRaise ex
37
+ | ex ->
38
+ sprintf
39
+ " Unexpected exception happened in the retry loop, ex = %s "
40
+ ( ex.ToString())
41
+ |> TorLogger.Log
42
+
43
+ return raise <| FSharpUtil.ReRaise ex
44
+ }
0 commit comments