11[<AutoOpen>]
2- module Equinox.Tool.Infrastructure.Prelude
2+ module internal Equinox.Tool.Infrastructure.Prelude
33
4+ open Equinox.Tools .TestHarness .HttpHelpers
45open System
56open System.Diagnostics
67open System.Text
7- open System.Threading
88
99type Exception with
1010 // https://github.com/fsharp/fslang-suggestions/issues/660
11- member this.Reraise () =
11+ member this.Reraise () =
1212 ( System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture this) .Throw ()
1313 Unchecked.defaultof<_>
1414
@@ -17,7 +17,7 @@ type Async with
1717 /// Raises an exception using Async's continuation mechanism directly.
1818 /// </summary >
1919 /// <param name =" exn " >Exception to be raised.</param >
20- static member Raise ( exn : #exn ) = Async.FromContinuations( fun ( _ , ec , _ ) -> ec exn)
20+ static member Raise ( exn : #exn ) = Async.FromContinuations( fun ( _ , ec , _ ) -> ec exn)
2121
2222 /// <summary >
2323 /// Gets the result of given task so that in the event of exception
@@ -33,7 +33,7 @@ type Async with
3333 let e = t.Exception
3434 if e.InnerExceptions.Count = 1 then ec e.InnerExceptions.[ 0 ]
3535 else ec e
36- elif t.IsCanceled then ec( new System.Threading.Tasks.TaskCanceledException())
36+ elif t.IsCanceled then ec( System.Threading.Tasks.TaskCanceledException())
3737 else sc t.Result)
3838 |> ignore)
3939 [<DebuggerStepThrough>]
@@ -49,40 +49,12 @@ type Async with
4949 else
5050 sc ())
5151 |> ignore)
52- /// Creates an async computation which runs the provided sequence of computations and completes
53- /// when all computations in the sequence complete. Up to parallelism computations will
54- /// be in-flight at any given point in time. Error or cancellation of any computation in
55- /// the sequence causes the resulting computation to error or cancel, respectively.
56- /// Like Async.Parallel but with support for throttling.
57- /// Note that an array is allocated to contain the results of all computations.
58- static member ParallelThrottled ( parallelism : int ) ( tasks : seq < Async < 'T >>) : Async < 'T []> = async {
59- if parallelism < 1 then invalidArg " parallelism" " Must be positive number."
60- use semaphore = new SemaphoreSlim( parallelism)
61- let throttledWorker ( task : Async < 'T >) = async {
62- let! ct = Async.CancellationToken
63- do ! semaphore.WaitAsync ct |> Async.AwaitTaskCorrect
64- try return ! task
65- finally ignore( semaphore.Release())
66- }
67-
68- return ! tasks |> Seq.map throttledWorker |> Async.Parallel
69- }
70-
71- type StringBuilder with
72- member sb.Appendf fmt = Printf.ksprintf ( ignore << sb.Append) fmt
73- member sb.Appendfn fmt = Printf.ksprintf ( ignore << sb.AppendLine) fmt
74-
75- static member inline Build ( builder : StringBuilder -> unit ) =
76- let instance = StringBuilder() // TOCONSIDER PooledStringBuilder.GetInstance()
77- builder instance
78- instance.ToString()
7952
8053[<AutoOpen>]
8154module HttpHelpers =
8255
8356 open System.Net
8457 open System.Net .Http
85- open System.Runtime .Serialization
8658
8759 /// Operations on System.Net.HttpRequestMessage
8860 module HttpReq =
@@ -138,25 +110,12 @@ module HttpHelpers =
138110 request.Headers.Add( name, value)
139111 request
140112
141- type HttpContent with
142- member c.ReadAsString () = async {
143- match c with
144- | null -> return null
145- | c -> return ! c.ReadAsStringAsync() |> Async.AwaitTaskCorrect
146- }
147-
148- // only intended for logging under control of InvalidHttpResponseException, hence the esoteric name
149- member internal c.ReadAsStringDiapered () = async {
150- try return ! c.ReadAsString()
151- with : ? ObjectDisposedException -> return "< HttpContent : ObjectDisposedException > "
152- }
153-
154113 type HttpClient with
155114 /// <summary >
156115 /// Drop-in replacement for HttpClient.SendAsync which addresses known timeout issues
157116 /// </summary >
158117 /// <param name =" msg " >HttpRequestMessage to be submitted.</param >
159- member client.Send ( msg : HttpRequestMessage ) = async {
118+ member client.SendAsync2 ( msg : HttpRequestMessage ) = async {
160119 let! ct = Async.CancellationToken
161120 try return ! client.SendAsync( msg, ct) |> Async.AwaitTaskCorrect
162121 // address https://github.com/dotnet/corefx/issues/20296
@@ -169,67 +128,6 @@ module HttpHelpers =
169128 return ! Async.Raise( TimeoutException message)
170129 }
171130
172- /// Exception indicating an unexpected response received by an Http Client
173- type InvalidHttpResponseException =
174- inherit Exception
175-
176- // TODO: include headers
177- val private userMessage : string
178- val private requestMethod : string
179- val RequestUri : Uri
180- val RequestBody : string
181- val StatusCode : HttpStatusCode
182- val ReasonPhrase : string
183- val ResponseBody : string
184-
185- member __.RequestMethod = new HttpMethod(__. requestMethod)
186-
187- private new ( userMessage : string , requestMethod : HttpMethod , requestUri : Uri , requestBody : string ,
188- statusCode : HttpStatusCode , reasonPhrase : string , responseBody : string ,
189- ? innerException : exn ) =
190- {
191- inherit Exception( message = null , innerException = defaultArg innerException null ) ; userMessage = userMessage ;
192- requestMethod = string requestMethod ; RequestUri = requestUri ; RequestBody = requestBody ;
193- StatusCode = statusCode ; ReasonPhrase = reasonPhrase ; ResponseBody = responseBody
194- }
195-
196- override e.Message =
197- StringBuilder.Build( fun sb ->
198- sb.Appendfn " %s %O RequestUri=%O HttpStatusCode=%O " e.userMessage e.RequestMethod e.RequestUri e.StatusCode
199- let getBodyString str = if String.IsNullOrWhiteSpace str then " <null>" else str
200- sb.Appendfn " RequestBody=%s " ( getBodyString e.RequestBody)
201- sb.Appendfn " ResponseBody=%s " ( getBodyString e.ResponseBody))
202-
203- interface ISerializable with
204- member e.GetObjectData ( si : SerializationInfo , sc : StreamingContext ) =
205- let add name ( value : obj ) = si.AddValue( name, value)
206- base .GetObjectData( si, sc) ; add " userMessage" e.userMessage ;
207- add " requestUri" e.RequestUri ; add " requestMethod" e.requestMethod ; add " requestBody" e.RequestBody
208- add " statusCode" e.StatusCode ; add " reasonPhrase" e.ReasonPhrase ; add " responseBody" e.ResponseBody
209-
210- new ( si : SerializationInfo , sc : StreamingContext ) =
211- let get name = si.GetValue( name, typeof< 'a>) :?> 'a
212- {
213- inherit Exception( si, sc) ; userMessage = get " userMessage" ;
214- RequestUri = get " requestUri" ; requestMethod = get " requestMethod" ; RequestBody = get " requestBody" ;
215- StatusCode = get " statusCode" ; ReasonPhrase = get " reasonPhrase" ; ResponseBody = get " responseBody"
216- }
217-
218- static member Create ( userMessage : string , response : HttpResponseMessage , ? innerException : exn ) = async {
219- let request = response.RequestMessage
220- let! responseBodyC = response.Content.ReadAsStringDiapered() |> Async.StartChild
221- let! requestBody = request.Content.ReadAsStringDiapered()
222- let! responseBody = responseBodyC
223- return
224- new InvalidHttpResponseException(
225- userMessage, request.Method, request.RequestUri, requestBody,
226- response.StatusCode, response.ReasonPhrase, responseBody,
227- ?innerException = innerException)
228- }
229-
230- static member Create ( response : HttpResponseMessage , ? innerException : exn ) =
231- InvalidHttpResponseException.Create( " HTTP request yielded unexpected response." , response, ?innerException = innerException)
232-
233131 type HttpResponseMessage with
234132
235133 /// Raises an <c >InvalidHttpResponseException</c > if the response status code does not match expected value.
@@ -264,4 +162,12 @@ module HttpHelpers =
264162
265163 /// Deserialize body using default Json.Net profile - throw with content details if StatusCode is not OK or decoding fails
266164 let deserializeOkJsonNet < 't > =
267- deserializeExpectedJsonNet< 't> HttpStatusCode.OK
165+ deserializeExpectedJsonNet< 't> HttpStatusCode.OK
166+
167+ type StringBuilder with
168+ member sb.Appendf fmt = Printf.ksprintf ( ignore << sb.Append) fmt
169+
170+ static member inline Build ( builder : StringBuilder -> unit ) =
171+ let instance = StringBuilder() // TOCONSIDER PooledStringBuilder.GetInstance()
172+ builder instance
173+ instance.ToString()
0 commit comments