If a reactor raises an error, it keeps reacting.
Chris Pressey
5 years ago
1 | 1 |
====
|
2 | 2 |
|
3 | 3 |
Test that circular definitions are not allowed.
|
4 | |
|
5 | |
Test that a reactor can raise an error and keep going.
|
6 | 4 |
|
7 | 5 |
Long-term
|
8 | 6 |
---------
|
200 | 200 |
= Cat
|
201 | 201 |
= Dog
|
202 | 202 |
|
|
203 |
If evaluating the transducer of a reactor raises an error, the reactor
|
|
204 |
remains in the same state and issues no commands, but always recovers
|
|
205 |
so that it can continue to handle subsequent events (i.e. it does not crash).
|
|
206 |
|
|
207 |
An implementation is encouraged to allow these to be logged (and the
|
|
208 |
reference implementation will display them if `--show-events` is given)
|
|
209 |
but this is not a strict requirement.
|
|
210 |
|
|
211 |
| (reactor (line-terminal) 0
|
|
212 |
| (macro (self args env)
|
|
213 |
| (bind event (head args)
|
|
214 |
| (bind event-type (head event)
|
|
215 |
| (bind event-payload (head (tail event))
|
|
216 |
| (if (equal? event-type (literal readln))
|
|
217 |
| (if (equal? (head event-payload) 65)
|
|
218 |
| (raise 999999)
|
|
219 |
| (list 0 (list (literal writeln) event-payload)))
|
|
220 |
| (list 0)))))))
|
|
221 |
+ Cat
|
|
222 |
+ Dog
|
|
223 |
+ Alligator
|
|
224 |
+ Bear
|
|
225 |
= Cat
|
|
226 |
= Dog
|
|
227 |
= Bear
|
|
228 |
|
203 | 229 |
Reactors can keep state.
|
204 | 230 |
|
205 | 231 |
| (define inc (macro (self args env)
|
|
0 |
(reactor (line-terminal) 0
|
|
1 |
(macro (self args env)
|
|
2 |
(bind event (head args)
|
|
3 |
(bind event-type (head event)
|
|
4 |
(bind event-payload (head (tail event))
|
|
5 |
(if (equal? event-type (literal readln))
|
|
6 |
(if (equal? (head event-payload) 65)
|
|
7 |
(raise 999999)
|
|
8 |
(list 0 (list (literal writeln) event-payload)))
|
|
9 |
(list 0)))))))
|
16 | 16 |
|
17 | 17 |
update :: Reactor -> Expr -> (Reactor, [Expr])
|
18 | 18 |
update reactor@Reactor{rid=rid, env=env, state=state, body=body} event =
|
19 | |
case eval (IEnv stop) env (List [body, event, state]) id of
|
|
19 |
case eval (IEnv catchException) env (List [body, event, state]) id of
|
|
20 |
command@(List [(Symbol "uncaught-exception"), expr]) ->
|
|
21 |
(reactor, [command])
|
20 | 22 |
(List (state':commands)) ->
|
21 | 23 |
(reactor{ state=state' }, applyStop commands)
|
22 | |
_ ->
|
23 | |
-- in actuality, this is an error and we should log it etc.
|
24 | |
(reactor, [])
|
|
24 |
expr ->
|
|
25 |
(reactor, [List [(Symbol "malformed-response"), expr]])
|
25 | 26 |
where
|
|
27 |
catchException expr = List [(Symbol "uncaught-exception"), expr]
|
|
28 |
|
26 | 29 |
-- If the reactor issued a 'stop' command, decorate that command
|
27 | 30 |
-- with the rid of the reactor, so the event loop knows which
|
28 | 31 |
-- reactor to stop.
|