git @ Cat's Eye Technologies Robin / fafee84
If a reactor raises an error, it keeps reacting. Chris Pressey 5 years ago
4 changed file(s) with 43 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
11 ====
22
33 Test that circular definitions are not allowed.
4
5 Test that a reactor can raise an error and keep going.
64
75 Long-term
86 ---------
200200 = Cat
201201 = Dog
202202
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
203229 Reactors can keep state.
204230
205231 | (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)))))))
1616
1717 update :: Reactor -> Expr -> (Reactor, [Expr])
1818 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])
2022 (List (state':commands)) ->
2123 (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]])
2526 where
27 catchException expr = List [(Symbol "uncaught-exception"), expr]
28
2629 -- If the reactor issued a 'stop' command, decorate that command
2730 -- with the rid of the reactor, so the event loop knows which
2831 -- reactor to stop.