@@ -18,16 +18,16 @@ type internal AsyncBatch<'Req, 'Res>() =
18
18
// sadly there's no way to detect without a try/catch
19
19
try queue.TryAdd( item)
20
20
with :? InvalidOperationException -> false
21
- let mutable attempt = Unchecked.defaultof< Lazy< Task< 'Res[] >>>
21
+ let mutable attempt = Unchecked.defaultof< Lazy< Task< 'Res>>>
22
22
23
23
/// Attempt to add a request to the flight
24
24
/// Succeeds during linger interval (which commences when the first caller triggers the workflow via AwaitResult)
25
25
/// Fails if this flight has closed (caller should initialize a fresh Batch, potentially holding off until the current attempt completes)
26
- member _.TryAdd ( req , dispatch : Func < 'Req [], CancellationToken , Task < 'Res [] >>, lingerMs : int , limiter : System.Threading.SemaphoreSlim voption , ct ) =
26
+ member _.TryAdd ( req , dispatch : Func < 'Req [], CancellationToken , Task < 'Res >>, lingerMs : int , limiter : System.Threading.SemaphoreSlim voption , ct ) =
27
27
if not ( tryEnqueue req) then false else
28
28
29
- // Prepare a new instance, with cancellation under our control (it won't start until the Force triggers it though)
30
- let newInstance : Lazy < Task < 'Res [] >> = lazy task {
29
+ // Prepare a new instance, with cancellation under our control (it won't start until the .Value triggers it though)
30
+ let newInstance : Lazy < Task < 'Res >> = lazy task {
31
31
do ! Task.Delay( lingerMs, ct)
32
32
match limiter with ValueNone -> () | ValueSome s -> do ! s.WaitAsync( ct)
33
33
try queue.CompleteAdding()
@@ -45,12 +45,12 @@ type internal AsyncBatch<'Req, 'Res>() =
45
45
/// Requests are added to pending batch during the wait period, which consists of two phases:
46
46
/// 1. a defined linger period (min 1ms)
47
47
/// 2. (optionally) a wait to acquire capacity on a limiter semaphore (e.g. one might have a limit on concurrent dispatches across a pool)
48
- type Batcher < 'Req , 'Res > private ( tryInclude : Func < AsyncBatch < _ , _ >, 'Req , CancellationToken , bool > ) =
48
+ type Batcher < 'Req , 'Res > private ( tryInclude : Func < AsyncBatch < 'Req , 'Res >, 'Req , CancellationToken , bool > ) =
49
49
let mutable cell = AsyncBatch< 'Req, 'Res>()
50
- new ( dispatch: Func< 'Req[], CancellationToken, Task< 'Res[] >>, lingerMs, limiter) =
50
+ new ( dispatch: Func< 'Req[], CancellationToken, Task< 'Res>>, lingerMs, limiter) =
51
51
if lingerMs < 1 then invalidArg ( nameof( lingerMs)) " Minimum linger period is 1ms" // concurrent waiters need to add work to the batch across their threads
52
52
Batcher( fun cell req ct -> cell.TryAdd( req, dispatch, lingerMs, limiter, ct = ct))
53
- new ( dispatch: 'Req[] -> Async< 'Res[] >, ?linger : TimeSpan,
53
+ new ( dispatch: 'Req[] -> Async< 'Res>, ?linger: TimeSpan,
54
54
// Extends the linger phase to include a period during which we await capacity on an externally managed Semaphore
55
55
// The Batcher doesn't care, but a typical use is to enable limiting the number of concurrent in-flight dispatches
56
56
?limiter) =
@@ -99,7 +99,7 @@ type BatcherCache<'Id, 'Entry>(cache: Cache<'Entry>, toKey: Func<'Id, string>, c
99
99
let mapKey = Func< 'Id, string>( fun id -> " $Batcher-" + string id)
100
100
BatcherCache( Cache cache, mapKey, createEntry, ?cacheWindow = cacheWindow)
101
101
102
- member _.GetOrAdd ( id : 'Id ) : 'Entry =
102
+ member _.GetOrAdd ( id : 'Id ) : 'Entry =
103
103
// Optimise for low allocations on happy path
104
104
let key = toKey.Invoke( id)
105
105
match cache.TryGet key with
0 commit comments