@@ -18,6 +18,14 @@ let waitFor (mre: ManualResetEvent) =
1818 if not <| mre.WaitOne timeout then
1919 failwith " waitFor timed out"
2020
21+ let waitUntil condition value =
22+ task {
23+ let sw = Stopwatch.StartNew()
24+ while not <| condition value do
25+ if sw.Elapsed > timeout then
26+ failwith " waitUntil timed out"
27+ do ! Task.Delay 10
28+ }
2129
2230let rec internal spinFor ( duration : TimeSpan ) =
2331 node {
@@ -29,6 +37,24 @@ let rec internal spinFor (duration: TimeSpan) =
2937 }
3038
3139
40+ type internal EventRecorder < 'a , 'b , 'c when 'a : equality and 'b : equality >( memoize : AsyncMemoize < 'a , 'b , 'c >) as self =
41+
42+ let events = ConcurrentQueue()
43+
44+ do memoize.OnEvent self.Add
45+
46+ member _.Add ( e , ( _label , k , _version )) = events.Enqueue ( e, k)
47+
48+ member _.Received value = events |> Seq.exists ( fst >> (=) value)
49+
50+ member _.CountOf value count = events |> Seq.filter ( fst >> (=) value) |> Seq.length |> (=) count
51+
52+ member _.ShouldBe ( expected ) =
53+ let expected = expected |> Seq.toArray
54+ let actual = events |> Seq.toArray
55+ Assert.Equal<_ array>( expected, actual)
56+
57+
3258[<Fact>]
3359let ``Basics`` () =
3460
@@ -69,21 +95,14 @@ let ``We can cancel a job`` () =
6995
7096 let jobStarted = new ManualResetEvent( false )
7197
72- let jobCanceled = new ManualResetEvent( false )
73-
7498 let computation action = node {
7599 action() |> ignore
76100 do ! spinFor timeout
77101 failwith " Should be canceled before it gets here"
78102 }
79103
80- let eventLog = ConcurrentQueue()
81- let memoize = AsyncMemoize< int, int, _>()
82- memoize.OnEvent( fun ( e , ( _label , k , _version )) ->
83- eventLog.Enqueue ( e, k)
84- if e = Canceled then
85- jobCanceled.Set() |> ignore
86- )
104+ let memoize = AsyncMemoize<_, int, _>()
105+ let events = EventRecorder( memoize)
87106
88107 use cts1 = new CancellationTokenSource()
89108 use cts2 = new CancellationTokenSource()
@@ -96,13 +115,10 @@ let ``We can cancel a job`` () =
96115 waitFor jobStarted
97116 jobStarted.Reset() |> ignore
98117
99- let jobRequested = new ManualResetEvent( false )
100- memoize.OnEvent( fun ( e , _ ) -> if e = Requested then jobRequested.Set() |> ignore)
101-
102118 let _task2 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation ignore), ct = cts2.Token)
103119 let _task3 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation ignore), ct = cts3.Token)
104120
105- waitFor jobRequested
121+ do ! waitUntil ( events.CountOf Requested ) 3
106122
107123 cts1.Cancel()
108124 cts2.Cancel()
@@ -111,16 +127,16 @@ let ``We can cancel a job`` () =
111127
112128 cts3.Cancel()
113129
114- waitFor jobCanceled
130+ do ! waitUntil events.Received Canceled
115131
116- Assert.Equal <( JobEvent * int ) array >([|
132+ events.ShouldBe [
117133 Requested, key
118134 Started, key
119135 Requested, key
120136 Requested, key
121137 Restarted, key
122138 Canceled, key
123- |], eventLog |> Seq.toArray )
139+ ]
124140 }
125141
126142[<Fact>]
@@ -136,9 +152,9 @@ let ``Job is restarted if first requestor cancels`` () =
136152 return key * 2
137153 }
138154
139- let eventLog = ConcurrentStack ()
140- let memoize = AsyncMemoize < int , int , _>( )
141- memoize.OnEvent ( fun ( e , ( _ , k , _version )) -> eventLog.Push ( e , k ))
155+ let memoize = AsyncMemoize <_, int , _> ()
156+ let events = EventRecorder ( memoize )
157+
142158
143159 use cts1 = new CancellationTokenSource()
144160 use cts2 = new CancellationTokenSource()
@@ -151,13 +167,10 @@ let ``Job is restarted if first requestor cancels`` () =
151167 waitFor jobStarted
152168 jobStarted.Reset() |> ignore
153169
154- let jobRequested = new ManualResetEvent( false )
155- memoize.OnEvent( fun ( e , _ ) -> if e = Requested then jobRequested.Set() |> ignore)
156-
157170 let _task2 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation key), ct = cts2.Token)
158171 let _task3 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation key), ct = cts3.Token)
159172
160- waitFor jobRequested
173+ do ! waitUntil ( events.CountOf Requested ) 3
161174
162175 cts1.Cancel()
163176
@@ -168,16 +181,13 @@ let ``Job is restarted if first requestor cancels`` () =
168181 let! result = _ task2
169182 Assert.Equal( 2 , result)
170183
171- let orderedLog = eventLog |> Seq.rev |> Seq.toList
172- let expected = [
184+ events.ShouldBe [
173185 Requested, key
174186 Started, key
175187 Requested, key
176188 Requested, key
177189 Restarted, key
178190 Finished, key ]
179-
180- Assert.Equal<_ list>( expected, orderedLog)
181191 }
182192
183193[<Fact>]
@@ -192,10 +202,10 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
192202 waitFor jobCanComplete
193203 return key * 2
194204 }
205+
206+ let memoize = AsyncMemoize<_, int, _>()
207+ let events = EventRecorder( memoize)
195208
196- let eventLog = ConcurrentStack()
197- let memoize = AsyncMemoize< int, int, _>()
198- memoize.OnEvent( fun ( e , ( _label , k , _version )) -> eventLog.Push ( e, k))
199209
200210 use cts1 = new CancellationTokenSource()
201211 use cts2 = new CancellationTokenSource()
@@ -208,13 +218,10 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
208218 waitFor jobStarted
209219 jobStarted.Reset() |> ignore
210220
211- let jobRequested = new ManualResetEvent( false )
212- memoize.OnEvent( fun ( e , _ ) -> if e = Requested then jobRequested.Set() |> ignore)
213-
214221 let _task2 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation key), ct = cts2.Token)
215222 let _task3 = NodeCode.StartAsTask_ ForTesting( memoize.Get'( key, computation key), ct = cts3.Token)
216223
217- waitFor jobRequested
224+ do ! waitUntil ( events.CountOf Requested ) 3
218225
219226 cts1.Cancel()
220227
@@ -227,16 +234,13 @@ let ``Job is restarted if first requestor cancels but keeps running if second re
227234 let! result = _ task3
228235 Assert.Equal( 2 , result)
229236
230- let orderedLog = eventLog |> Seq.rev |> Seq.toList
231- let expected = [
237+ events.ShouldBe [
232238 Requested, key
233239 Started, key
234240 Requested, key
235241 Requested, key
236242 Restarted, key
237243 Finished, key ]
238-
239- Assert.Equal<_ list>( expected, orderedLog)
240244 }
241245
242246
0 commit comments