X-Git-Url: https://jxself.org/git/?p=8sync.git;a=blobdiff_plain;f=doc%2F8sync-new-manual.org;h=bd6bb319fad467e154d23b77122209099d523d22;hp=ebbd13a9da880596e10181cc471dcc5c551ce399;hb=67e7474e551af5991ba4c5e3d686785a1aaa1d42;hpb=063be529581b7004dae5ecb106bcf33729b9fef7 diff --git a/doc/8sync-new-manual.org b/doc/8sync-new-manual.org index ebbd13a..bd6bb31 100644 --- a/doc/8sync-new-manual.org +++ b/doc/8sync-new-manual.org @@ -552,7 +552,7 @@ IRC> /query examplebot Horray! -** Writing our own actors and sending messages between them +** Writing our own actors Let's write the most basic, boring actor possible. How about an actor that start sleeping, and keeps sleeping? @@ -642,7 +642,7 @@ reference other actors. (work-on-this worker-work-on-this)))) (define (worker-work-on-this worker message difficulty) - "" + "Work on one task until done." (set! (worker-task-left worker) difficulty) (display "worker> Whatever you say, boss!\n") (while (and (actor-alive? worker) @@ -650,12 +650,11 @@ reference other actors. (display "worker> *huff puff*\n") (set! (worker-task-left worker) (- (worker-task-left worker) 1)) - (8sync (/ 1 3))) - (display "worker> Looks like I'm done! Can I go home yet?\n")) + (8sleep (/ 1 3)))) #+END_SRC The worker also contains familiar code, but we now see that we can -call 8sync with non-integer real numbers. +call 8sleep with non-integer real numbers. Looks like there's nothing left to do but run it: @@ -675,7 +674,6 @@ worker> *huff puff* worker> *huff puff* worker> *huff puff* worker> *huff puff* -worker> Looks like I'm done! Can I go home yet? #+END_SRC "<-" pays no attention to what happens with the messages it has sent @@ -701,7 +699,8 @@ into a micromanager. (<- (manager-direct-report manager) 'work-on-this difficulty) - ;; call the micromanagement loop + ;; Wait a moment, then call the micromanagement loop + (8sleep (/ 1 2)) (manager-micromanage-loop manager)) ;;; And add the following @@ -709,25 +708,26 @@ into a micromanager. (define (manager-micromanage-loop manager) "Pester direct report until they're done with their task." (display "manager> Are you done yet???\n") - (let ((still-working - (msg-val (<-wait (manager-direct-report manager) - 'done-yet?)))) - (if still-working + (let ((worker-is-done + (mbody-val (<-wait (manager-direct-report manager) + 'done-yet?)))) + (if worker-is-done + (begin (display "manager> Oh! I guess you can go home then.\n") + (<- (manager-direct-report manager) 'go-home)) (begin (display "manager> Harumph!\n") - (8sleep 1) + (8sleep (/ 1 2)) (when (actor-alive? manager) - (manager-micromanage-loop manager))) - (begin (display "manager> Oh! I guess you can go home then.\n") - (<- (manager-direct-report manager) 'go-home))))) + (manager-micromanage-loop manager)))))) #+END_SRC We've appended a micromanagement loop here... but what's going on? "<-wait", as it sounds, waits for a reply, and returns a reply message. In this case there's a value in the body of the message we want, -so we pull it out with msg-val. +so we pull it out with mbody-val. (It's possible for a remote actor to return multiple values, in which -case we'd want to use msg-receive, but that's a bit more complicated.) +case we'd want to use mbody-receive, but that's a bit more +complicated.) Of course, we need to update our worker accordingly as well. @@ -746,15 +746,54 @@ Of course, we need to update our worker accordingly as well. ;;; New procedures: (define (worker-done-yet? worker message) "Reply with whether or not we're done yet." - (<-reply message - (= (worker-task-left worker) 0))) + (let ((am-i-done? (= (worker-task-left worker) 0))) + (if am-i-done? + (display "worker> Yes, I finished up!\n") + (display "worker> No... I'm still working on it...\n")) + (<-reply message am-i-done?))) (define (worker-go-home worker message) "It's off of work for us!" - (display "worker> Whew! Free at last.") + (display "worker> Whew! Free at last.\n") (self-destruct worker)) #+END_SRC +(As you've probably guessed, you wouldn't normally call =display= +everywhere as we are in this program... that's just to make the +examples more illustrative.) + +Running it is the same as before: + +#+BEGIN_SRC scheme + (let* ((hive (make-hive)) + (worker (bootstrap-actor hive )) + (manager (bootstrap-actor hive + #:direct-report worker))) + (run-hive hive (list (bootstrap-message hive manager 'assign-task 5)))) +#+END_SRC + +But the output is a bit different: + +#+BEGIN_SRC scheme +manager> Work on this task for me! +worker> Whatever you say, boss! +worker> *huff puff* +worker> *huff puff* +manager> Are you done yet??? +worker> No... I'm still working on it... +manager> Harumph! +worker> *huff puff* +manager> Are you done yet??? +worker> *huff puff* +worker> No... I'm still working on it... +manager> Harumph! +worker> *huff puff* +manager> Are you done yet??? +worker> Yes, I finished up! +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 @@ -779,6 +818,15 @@ Ka-poof! ** COMMENT Websockets * Addendum +** Recommended .emacs additions + +In order for =mbody-receive= to indent properly, put this in your +.emacs: + +#+BEGIN_SRC emacs-lisp +(put 'mbody-receive 'scheme-indent-function 2) +#+END_SRC + ** 8sync and Fibers One other major library for asynchronous communication in Guile-land