Our while loop also checks "actor-alive?" to see whether or not
it is still registered.
In general, if you keep a loop in your actor that regularly yields
-to the scheduler, you should check this.
+to the scheduler, you should check this.[fn:actor-alive-deprecated-soon]
(An alternate way to handle it would be to not use a while loop at all
but simply send a message to ourselves with "<-" to call the
sleeper-loop handler again.
worker> Whew! Free at last.
#+END_SRC
+[fn:actor-alive-deprecated-soon]
+ Or rather, for now you should call =actor-alive?= if your code
+ is looping like this.
+ In the future, after an actor dies, its coroutines will
+ automatically be "canceled".
+
** Writing our own network-enabled actor
So, you want to write a networked actor!
(define-actor <telcmd> (<actor>)
((*init* telcmd-init)
(*cleanup* telcmd-cleanup)
- (new-client telcmd-new-client))
+ (new-client telcmd-new-client)
+ (handle-line telcmd-handle-line))
(socket #:accessor telcmd-socket
#:init-value #f))
#+END_SRC
(cond ((eof-object? line)
(close client))
(else
- (telcmd-handle-line telcmd client
- (string-trim-right line #\return))
+ (<- (actor-id telcmd) 'handle-line
+ client (string-trim-right line #\return))
(when (actor-alive? telcmd)
(loop)))))))
- (define (telcmd-handle-line telcmd client line)
+ (define (telcmd-handle-line telcmd message client line)
(match (string-split line #\space)
(("") #f) ; ignore empty lines
(("time" _ ...)
The actual method called whenever we have a "line" of input is pretty
straightforward... in fact it looks an awful lot like the IRC bot
handle-line procedure we used earlier.
-No surprises there!
+No surprises there![fn:why-send-a-message-to-handle-line]
Now let's run it:
finishes handling one message.
Our loop couldn't look quite like this though!
+[fn:why-send-a-message-to-handle-line]
+ Well, there may be one surprise to the astute observer.
+ Why are we sending a message to ourselves?
+ Couldn't we have just dropped the argument of "message" to
+ telcmd-handle-line and just called it like any other procedure?
+ Indeed, we /could/ do that, but sending a message to ourself has
+ an added advantage: if we accidentally "break" the
+ telcmd-handle-line procedure in some way (say we add a fun new
+ command we're playing with it), raising an exception won't break
+ and disconnect the client's main loop, it'll just break the
+ message handler for that one line, and our telcmd will happily
+ chug along accepting another command from the user while we try
+ to figure out what happened to the last one.
+
** An intermission: about live hacking
This section is optional, but highly recommended.