Examples

Here are a couple of practical examples of using Behn's %wait and %rest tasks.

%wait

Here we'll look at setting a timer by passing Behn a %wait task and taking the %wake gift it returns when the timer fires.

Below is a thread which will take a @dr as its argument and %passes Behn a %wait task to fire @dr in the future. When the timer fires, it'll then take the %wake gift and print it to the terminal along with the time that has elapsed.

wait.hoon

/- spider
/+ *strandio
=, strand=strand:spider
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=/ delay=@dr (need !<((unit @dr) arg))
;< t1=@da bind:m get-time
=/ =task:behn [%wait (add delay t1)]
=/ =card:agent:gall [%pass /timer %arvo %b task]
;< ~ bind:m (send-raw-card card)
;< res=(pair wire sign-arvo) bind:m take-sign-arvo
?> ?=([%timer ~] p.res)
?> ?=([%behn %wake *] q.res)
%- (slog ~[leaf+"Gift: {<+.q.res>}"])
?~ error.q.res
;< t2=@da bind:m get-time
%- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
(pure:m !>(~))
%- (slog u.error.q.res)
(pure:m !>(~))

Save the thread to /ted/wait.hoon and |commit %base. Then we can try running the thread with a @dr of ~s2:

> -wait ~s2
Gift: [%wake error=~]
Time elapsed: ~s2..0154

As you can see, the timer has fired successfully after ~s2 and Behn has given us a %wake gift.

%rest

Here we'll look at cancelling a previously set timer by passing Behn a %rest task.

Below is a variation on the %wake thread. It takes a @dr as its argument and sets a timer that far in the future, as before. However, it also sets a second timer twice the @dr in the future, and then cancels the first with a %rest task. If the %rest task succeeds in cancelling the first timer, the %wake gift will arrive after double the specified delay.

rest.hoon

/- spider
/+ *strandio
=, strand=strand:spider
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=/ delay=@dr (need !<((unit @dr) arg))
;< t1=@da bind:m get-time
=/ timer1=@da (add t1 delay)
=/ timer2=@da (add t1 (mul delay 2))
;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer1])
;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer2])
;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %rest timer1])
;< res=(pair wire sign-arvo) bind:m take-sign-arvo
?> ?=([%timer ~] p.res)
?> ?=([%behn %wake *] q.res)
%- (slog ~[leaf+"Gift: {<+.q.res>}"])
?~ error.q.res
;< t2=@da bind:m get-time
%- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
(pure:m !>(~))
%- (slog u.error.q.res)
(pure:m !>(~))

Save the above thread to /ted/rest.hoon, and |commit %base. Let's try run it with an argument of ~s2:

> -rest ~s2
Gift: [%wake error=~]
Time elapsed: ~s4..00d4

As you can see, the timer fired after four seconds, which means the two second timer was successfully cancelled by the %rest task.