doc: Add a note about actor-alive? being likely to be deprecated.
[8sync.git] / doc / 8sync-new-manual.org
index e1462f5e44c82cf60d2e67c5cd36822bf5dc673b..844653fa0b6a3da7eedd30ad376775d65fcc5759 100644 (file)
@@ -103,8 +103,8 @@ Now we need to add our bot.  Initially, it won't do much.
 #+BEGIN_SRC scheme
   (define-class <my-irc-bot> (<irc-bot>))
 
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     (if emote?
         (format #t "~a emoted ~s in channel ~a\n"
                 speaker line channel)
@@ -117,6 +117,11 @@ This is an 8sync actor.
 (8sync uses GOOPS to define actors.)
 We extended the handle-line generic method, so this is the code that
 will be called whenever the IRC bot "hears" anything.
+This method is itself an action handler, hence the second argument
+for =message=, which we can ignore for now.
+Pleasantly, the message's argument body is passed in as the rest of
+the arguments.
+
 For now the code is pretty basic: it just outputs whatever it "hears"
 from a user in a channel to the current output port.
 Pretty boring!
@@ -174,8 +179,8 @@ Let's get it to echo whatever we say back to us.
 Change handle-line to this:
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     (<- (actor-id irc-bot) 'send-line channel
         (format #f "Bawwwwk! ~a says: ~a" speaker line)))
 #+END_SRC
@@ -241,8 +246,8 @@ Indeed, we do have such a method, so we /could/ rewrite handle-line
 like so:
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     (irc-bot-send-line irc-bot channel
                        (format #f "Bawwwwk! ~a says: ~a" speaker line)))
 #+END_SRC
@@ -269,8 +274,8 @@ Whee, that looks like fun!
 To implement it, we're going to pull out Guile's pattern matcher.
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     (define my-name (irc-bot-username irc-bot))
     (define (looks-like-me? str)
       (or (equal? str my-name)
@@ -306,8 +311,8 @@ If you're getting the sense that we could make this a bit less wordy,
 you're right:
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     (define my-name (irc-bot-username irc-bot))
     (define (looks-like-me? str)
       (or (equal? str my-name)
@@ -404,7 +409,7 @@ and will always yield to the scheduler.
 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.
@@ -595,6 +600,20 @@ Of course, we need to update our worker accordingly as well.
 everywhere as we are in this program... that's just to make the
 examples more illustrative.)
 
+"<-reply" is what actually returns the information to the actor
+waiting on the reply.
+It takes as an argument the actor sending the message, the message
+it is in reply to, and the rest of the arguments are the "body" of
+the message.
+(If an actor handles a message that is being "waited on" but does not
+explicitly reply to it, an auto-reply with an empty body will be
+triggered so that the waiting actor is not left waiting around.)
+
+The last thing to note is the call to "self-destruct".
+This does what you might expect: it removes the actor from the hive.
+No new messages will be sent to it.
+Ka-poof!
+
 Running it is the same as before:
 
 #+BEGIN_SRC scheme
@@ -627,19 +646,11 @@ manager> Oh!  I guess you can go home then.
 worker> Whew!  Free at last.
 #+END_SRC
 
-"<-reply" is what actually returns the information to the actor
-waiting on the reply.
-It takes as an argument the actor sending the message, the message
-it is in reply to, and the rest of the arguments are the "body" of
-the message.
-(If an actor handles a message that is being "waited on" but does not
-explicitly reply to it, an auto-reply with an empty body will be
-triggered so that the waiting actor is not left waiting around.)
-
-The last thing to note is the call to "self-destruct".
-This does what you might expect: it removes the actor from the hive.
-No new messages will be sent to it.
-Ka-poof!
+[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
 
@@ -655,7 +666,8 @@ Well, luckily that's pretty easy, especially with all you know so far.
   (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
@@ -735,12 +747,12 @@ In our case, we politely close the socket when =<telcmd>= dies.
         (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" _ ...)
@@ -765,7 +777,7 @@ agenda.[fn:setvbuf]
 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:
 
@@ -819,6 +831,20 @@ Happy hacking!
   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.
@@ -929,8 +955,8 @@ Edit the respond section to see what channel it's really sending
 things to:
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     ;; [... snip ...]
     (define (respond respond-line)
       (<- (actor-id irc-bot) 'send-line (pk 'channel channel)
@@ -959,8 +985,8 @@ to looks like our own username that we respond back to the sender.
 (We can remove the pk now that we know what's going on.)
 
 #+BEGIN_SRC scheme
-  (define-method (handle-line (irc-bot <my-irc-bot>) speaker channel
-                              line emote?)
+  (define-method (handle-line (irc-bot <my-irc-bot>) message
+                              speaker channel line emote?)
     ;; [... snip ...]
     (define (respond respond-line)
       (<- (actor-id irc-bot) 'send-line