Skip to content

Commit 16d5ba4

Browse files
committed
Replace later with delay
1 parent c347744 commit 16d5ba4

File tree

4 files changed

+68
-70
lines changed

4 files changed

+68
-70
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"purescript-functions": "^3.0.0",
2323
"purescript-parallel": "^3.0.0",
2424
"purescript-transformers": "^3.0.0",
25-
"purescript-unsafe-coerce": "^3.0.0"
25+
"purescript-unsafe-coerce": "^3.0.0",
26+
"purescript-datetime": "^3.0.0"
2627
},
2728
"devDependencies": {
2829
"purescript-partial": "^1.2.0"

src/Control/Monad/Aff.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,29 @@ exports._cancelWith = function (nonCanceler, aff, canceler1) {
3636
};
3737
};
3838

39-
exports._setTimeout = function (nonCanceler, millis, aff) {
39+
exports._delay = function (nonCanceler, millis) {
4040
var set = setTimeout;
4141
var clear = clearTimeout;
4242
if (millis <= 0 && typeof setImmediate === "function") {
4343
set = setImmediate;
4444
clear = clearImmediate;
4545
}
46-
return function (success, error) {
47-
var canceler;
48-
49-
var timeout = set(function () {
50-
canceler = aff(success, error);
46+
return function (success) {
47+
var timedOut = false;
48+
var timer = set(function () {
49+
timedOut = true;
50+
success();
5151
}, millis);
5252

53-
return function (e) {
54-
return function (s, f) {
55-
if (canceler !== undefined) {
56-
return canceler(e)(s, f);
53+
return function () {
54+
return function (s) {
55+
if (timedOut) {
56+
s(false);
5757
} else {
58-
clear(timeout);
58+
clear(timer);
5959
s(true);
60-
return nonCanceler;
6160
}
61+
return nonCanceler;
6262
};
6363
};
6464
};

src/Control/Monad/Aff.purs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ module Control.Monad.Aff
99
, finally
1010
, forkAff
1111
, forkAll
12-
, later
13-
, later'
12+
, delay
1413
, launchAff
1514
, liftEff'
1615
, makeAff
@@ -39,6 +38,7 @@ import Data.Foldable (class Foldable, foldl)
3938
import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3)
4039
import Data.Monoid (class Monoid, mempty)
4140
import Data.Newtype (class Newtype)
41+
import Data.Time.Duration (Milliseconds(..))
4242

4343
import Unsafe.Coerce (unsafeCoerce)
4444

@@ -107,14 +107,9 @@ makeAff h = makeAff' (\e a -> const nonCanceler <$> h e a)
107107
makeAff' :: forall e a. ((Error -> Eff e Unit) -> (a -> Eff e Unit) -> Eff e (Canceler e)) -> Aff e a
108108
makeAff' h = _makeAff h
109109

110-
-- | Runs the asynchronous computation off the current execution context.
111-
later :: forall e a. Aff e a -> Aff e a
112-
later = later' 0
113-
114-
-- | Runs the specified asynchronous computation later, by the specified
115-
-- | number of milliseconds.
116-
later' :: forall e a. Int -> Aff e a -> Aff e a
117-
later' n aff = runFn3 _setTimeout nonCanceler n aff
110+
-- | Pauses execuation of the current computation for the specified number of milliseconds.
111+
delay :: forall e. Milliseconds -> Aff e Unit
112+
delay (Milliseconds n) = runFn2 _delay nonCanceler n
118113

119114
-- | Compute `aff1`, followed by `aff2` regardless of whether `aff1` terminated successfully.
120115
finally :: forall e a b. Aff e a -> Aff e b -> Aff e a
@@ -284,7 +279,7 @@ fromAVBox = unsafeCoerce
284279

285280
foreign import _cancelWith :: forall e a. Fn3 (Canceler e) (Aff e a) (Canceler e) (Aff e a)
286281

287-
foreign import _setTimeout :: forall e a. Fn3 (Canceler e) Int (Aff e a) (Aff e a)
282+
foreign import _delay :: forall e a. Fn2 (Canceler e) Number (Aff e a)
288283

289284
foreign import _unsafeInterleaveAff :: forall e1 e2 a. Aff e1 a -> Aff e2 a
290285

test/Test/Main.purs

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module Test.Main where
33
import Prelude
44

55
import Control.Alt ((<|>))
6-
import Control.Monad.Aff (Aff, runAff, makeAff, launchAff, later, later', forkAff, forkAll, Canceler(..), cancel, attempt, finally, apathize)
6+
import Control.Monad.Aff (Aff, runAff, makeAff, launchAff, delay, forkAff, forkAll, Canceler(..), cancel, attempt, finally, apathize)
77
import Control.Monad.Aff.AVar (AVAR, makeVar, makeVar', putVar, modifyVar, takeVar, peekVar, killVar)
88
import Control.Monad.Aff.Console (CONSOLE, log)
99
import Control.Monad.Eff (Eff)
@@ -14,16 +14,17 @@ import Control.Monad.Rec.Class (Step(..), tailRecM)
1414
import Control.Parallel (parallel, sequential)
1515
import Data.Either (either, fromLeft, fromRight)
1616
import Data.Maybe (Maybe(..))
17+
import Data.Time.Duration (Milliseconds(..))
1718
import Data.Unfoldable (replicate)
1819
import Partial.Unsafe (unsafePartial)
1920

2021
type Test a = forall e. Aff (console :: CONSOLE | e) a
2122
type TestAVar a = forall e. Aff (console :: CONSOLE, avar :: AVAR | e) a
2223

23-
timeout :: Int TestAVar Unit TestAVar Unit
24+
timeout :: Milliseconds TestAVar Unit TestAVar Unit
2425
timeout ms aff = do
2526
exn <- makeVar
26-
clr1 <- forkAff (later' ms (putVar exn (Just "Timed out")))
27+
clr1 <- forkAff (delay ms *> putVar exn (Just "Timed out"))
2728
clr2 <- forkAff (aff *> putVar exn Nothing)
2829
res ← takeVar exn
2930
log (show res)
@@ -37,7 +38,8 @@ replicateArray = replicate
3738
test_sequencing :: Int -> Test Unit
3839
test_sequencing 0 = log "Done"
3940
test_sequencing n = do
40-
later' 100 (log (show (n / 10) <> " seconds left"))
41+
delay $ Milliseconds 100.0
42+
log (show (n / 10) <> " seconds left")
4143
test_sequencing (n - 1)
4244

4345
foreign import synchronousUnexpectedThrowError :: forall e. Eff e Unit
@@ -75,30 +77,30 @@ test_apathize = do
7577
test_putTakeVar :: TestAVar Unit
7678
test_putTakeVar = do
7779
v <- makeVar
78-
_ <- forkAff (later $ putVar v 1.0)
80+
_ <- forkAff (delay (Milliseconds 0.0) *> putVar v 1.0)
7981
a <- takeVar v
8082
log ("Success: Value " <> show a)
8183

8284
test_peekVar :: TestAVar Unit
8385
test_peekVar = do
84-
timeout 1000 do
86+
timeout (Milliseconds 1000.0) do
8587
v <- makeVar
86-
_ <- forkAff (later $ putVar v 1.0)
88+
_ <- forkAff (delay (Milliseconds 0.0) *> putVar v 1.0)
8789
a1 <- peekVar v
8890
a2 <- takeVar v
8991
when (a1 /= a2) do
9092
throwError (error "Something horrible went wrong - peeked var is not equal to taken var")
9193
log ("Success: Peeked value not consumed")
9294

93-
timeout 1000 do
95+
timeout (Milliseconds 1000.0) do
9496
w <- makeVar
9597
putVar w true
9698
b <- peekVar w
9799
when (not b) do
98100
throwError (error "Something horrible went wrong - peeked var is not true")
99101
log ("Success: Peeked value read from written var")
100102

101-
timeout 1000 do
103+
timeout (Milliseconds 1000.0) do
102104
x <- makeVar
103105
res <- makeVar' 1
104106
_ <- forkAff do
@@ -116,7 +118,7 @@ test_peekVar = do
116118

117119
test_killFirstForked :: Test Unit
118120
test_killFirstForked = do
119-
c <- forkAff (later' 100 $ pure "Failure: This should have been killed!")
121+
c <- forkAff (delay (Milliseconds 100.0) $> "Failure: This should have been killed!")
120122
b <- c `cancel` (error "Just die")
121123
log (if b then "Success: Killed first forked" else "Failure: Couldn't kill first forked")
122124

@@ -144,8 +146,8 @@ test_finally = do
144146

145147
test_parRace :: TestAVar Unit
146148
test_parRace = do
147-
s <- sequential (parallel (later' 100 $ pure "Success: Early bird got the worm") <|>
148-
parallel (later' 200 $ pure "Failure: Late bird got the worm"))
149+
s <- sequential (parallel (delay (Milliseconds 100.0) $> "Success: Early bird got the worm") <|>
150+
parallel (delay (Milliseconds 200.0) $> "Failure: Late bird got the worm"))
149151
log s
150152

151153
test_parError :: TestAVar Unit
@@ -155,14 +157,14 @@ test_parError = do
155157

156158
test_parRaceKill1 :: TestAVar Unit
157159
test_parRaceKill1 = do
158-
s <- sequential (parallel (later' 100 $ throwError (error ("Oh noes!"))) <|>
159-
parallel (later' 200 $ pure "Success: Early error was ignored in favor of late success"))
160+
s <- sequential (parallel (delay (Milliseconds 100.0) *> throwError (error ("Oh noes!"))) <|>
161+
parallel (delay (Milliseconds 200.0) $> "Success: Early error was ignored in favor of late success"))
160162
log s
161163

162164
test_parRaceKill2 :: TestAVar Unit
163165
test_parRaceKill2 = do
164-
e <- attempt $ sequential (parallel (later' 100 $ throwError (error ("Oh noes!"))) <|>
165-
parallel (later' 200 $ throwError (error ("Oh noes!"))))
166+
e <- attempt $ sequential (parallel (delay (Milliseconds 100.0) *> throwError (error ("Oh noes!"))) <|>
167+
parallel (delay (Milliseconds 200.0) *> throwError (error ("Oh noes!"))))
166168
either (const $ log "Success: Killing both kills it dead") (const $ log "Failure: It's alive!!!") e
167169

168170
test_semigroupCanceler :: Test Unit
@@ -174,30 +176,32 @@ test_semigroupCanceler =
174176
log (if v then "Success: Canceled semigroup composite canceler"
175177
else "Failure: Could not cancel semigroup composite canceler")
176178

177-
test_cancelLater :: TestAVar Unit
178-
test_cancelLater = do
179-
c <- forkAff $ (do _ <- pure "Binding"
180-
_ <- later' 100 $ log ("Failure: Later was not canceled!")
181-
pure "Binding")
179+
test_cancelDelay :: TestAVar Unit
180+
test_cancelDelay = do
181+
c <- forkAff do
182+
_ <- pure "Binding"
183+
delay (Milliseconds 100.0)
184+
log $ "Failure: Delay was not canceled!"
185+
pure "Binding"
182186
v <- cancel c (error "Cause")
183-
log (if v then "Success: Canceled later" else "Failure: Did not cancel later")
187+
log (if v then "Success: Canceled delay" else "Failure: Did not cancel delay")
184188

185-
test_cancelLaunchLater :: forall e. Eff (console :: CONSOLE, exception :: EXCEPTION | e) Unit
186-
test_cancelLaunchLater = do
187-
c <- launchAff $ later' 100 $ log ("Failure: Later was not canceled!")
189+
test_cancelLaunchDelay :: forall e. Eff (console :: CONSOLE, exception :: EXCEPTION | e) Unit
190+
test_cancelLaunchDelay = do
191+
c <- launchAff $ delay (Milliseconds 100.0) *> log ("Failure: Delay was not canceled!")
188192
void $ launchAff $ (do v <- cancel c (error "Cause")
189-
log (if v then "Success: Canceled later" else "Failure: Did not cancel later"))
193+
log (if v then "Success: Canceled delay" else "Failure: Did not cancel delay"))
190194

191-
test_cancelRunLater :: forall e. Eff (console :: CONSOLE | e) Unit
192-
test_cancelRunLater = do
193-
c <- runAff (const (pure unit)) (const (pure unit)) $ later' 100 $ log ("Failure: Later was not canceled!")
195+
test_cancelRunDelay :: forall e. Eff (console :: CONSOLE | e) Unit
196+
test_cancelRunDelay = do
197+
c <- runAff (const (pure unit)) (const (pure unit)) $ delay (Milliseconds 100.0) *> log ("Failure: Delay was not canceled!")
194198
void $ try $ launchAff $ (do v <- cancel c (error "Cause")
195-
log (if v then "Success: Canceled later" else "Failure: Did not cancel later"))
199+
log (if v then "Success: Canceled delay" else "Failure: Did not cancel delay"))
196200

197201
test_cancelParallel :: TestAVar Unit
198202
test_cancelParallel = do
199-
c <- forkAff <<< sequential $ parallel (later' 100 $ log "Failure: #1 should not get through") <|>
200-
parallel (later' 100 $ log "Failure: #2 should not get through")
203+
c <- forkAff <<< sequential $ parallel (delay (Milliseconds 100.0) *> log "Failure: #1 should not get through") <|>
204+
parallel (delay (Milliseconds 100.0) *> log "Failure: #2 should not get through")
201205
v <- c `cancel` (error "Must cancel")
202206
log (if v then "Success: Canceling composite of two Parallel succeeded"
203207
else "Failure: Canceling composite of two Parallel failed")
@@ -222,7 +226,7 @@ loopAndBounce n = do
222226
where
223227
go 0 = pure (Done 0)
224228
go k | mod k 30000 == 0 = do
225-
later' 10 (pure unit)
229+
delay (Milliseconds 10.0)
226230
pure (Loop (k - 1))
227231
go k = pure (Loop (k - 1))
228232

@@ -235,20 +239,17 @@ all n = do
235239

236240
cancelAll :: forall eff. Int -> Aff (console :: CONSOLE, avar :: AVAR | eff) Unit
237241
cancelAll n = do
238-
canceler <- forkAll $ replicateArray n (later' 100000 (log "oops"))
242+
canceler <- forkAll $ replicateArray n (delay (Milliseconds 100000.0) *> log "oops")
239243
canceled <- cancel canceler (error "bye")
240244
log ("Cancelled all: " <> show canceled)
241245

242-
delay :: forall eff. Int -> Aff eff Unit
243-
delay n = later' n (pure unit)
244-
245246
main :: Eff (console :: CONSOLE, avar :: AVAR, exception :: EXCEPTION) Unit
246247
main = do
247-
Eff.log "Testing kill of later launched in separate Aff"
248-
test_cancelLaunchLater
248+
Eff.log "Testing kill of delay launched in separate Aff"
249+
test_cancelLaunchDelay
249250

250-
Eff.log "Testing kill of later run in separate Aff"
251-
test_cancelRunLater
251+
Eff.log "Testing kill of delay run in separate Aff"
252+
test_cancelRunDelay
252253

253254
void $ runAff throwException (const (pure unit)) $ do
254255
log "Testing sequencing"
@@ -263,11 +264,12 @@ main = do
263264
log "Testing attempt"
264265
test_attempt
265266

266-
log "Testing later"
267-
later $ log "Success: It happened later"
267+
log "Testing delay"
268+
delay (Milliseconds 0.0)
269+
log "Success: It happened later"
268270

269-
log "Testing kill of later"
270-
test_cancelLater
271+
log "Testing kill of delay"
272+
test_cancelDelay
271273

272274
log "Testing kill of first forked"
273275
test_killFirstForked
@@ -309,7 +311,7 @@ main = do
309311
test_syncTailRecM
310312

311313
log "pre-delay"
312-
delay 1000
314+
delay (Milliseconds 1000.0)
313315
log "post-delay"
314316

315317
loopAndBounce 1000000

0 commit comments

Comments
 (0)