Interleaved processing example.
authorTim Vaughan <tgvaughan@gmail.com>
Sun, 7 Jul 2019 19:58:20 +0000 (21:58 +0200)
committerTim Vaughan <tgvaughan@gmail.com>
Sun, 7 Jul 2019 19:58:20 +0000 (21:58 +0200)
actors.scm

index 9a1b630..8a581b9 100644 (file)
@@ -1,5 +1,7 @@
 (import srfi-69 matchable)
 
+(define trace-enabled #t)
+
 ;;;
 ;;; Actor creation
 ;;;
 ;;;
 
 (define (dispatch-message address message)
-  (print "Dispatching message " message " to " address)
-  (let* ((behaviour (hash-table-ref actor-table address))
-         (value (behaviour address message)))
-    (match value
-      ('done (hash-table-delete! actor-table address))
-      ('sleep 'do-nothing)
-      (else
-       hash-table-set! actor-table address value))))
+  (if trace-enabled
+      (print "Dispatching message " message " to " address))
+  (let ((behaviour (hash-table-ref/default actor-table address '())))
+    (if (null? behaviour)
+        (print "Warning: discarded message " message " to unknown actor " address)
+        (let ((value (apply behaviour (cons address message))))
+          (match value
+            ('done (hash-table-delete! actor-table address))
+            ('sleep 'do-nothing)
+            (else
+             hash-table-set! actor-table address value))))))
 
 ;;;
 ;;; FIFO queue implementation
       '()
       (fifo-pop message-queue)))
 
-(define (send-message actor message)
-  (print "Queued message " message " to " actor)
+(define (send-message actor . message)
+  (if trace-enabled
+      (print "Queued message " message " to " actor))
   (fifo-push message-queue (cons actor message)))
 
-(define (run)
+(define (process-next-message)
   (let ((addressed-msg (next-addressed-msg)))
     (if (null? addressed-msg)
-        'done
+        '()
         (let ((address (car addressed-msg))
               (message (cdr addressed-msg)))
-          (dispatch-message address message)
-          (run)))))
+          (dispatch-message address message)))))
+
+(define (run)
+  (unless (null? (process-next-message))
+    (run)))
+
+(define (send-and-run actor . message)
+  (apply send-message (cons actor message))
+  (run))
 
 ;;;
 ;;; Testing
 ;;;
 
 (define factorial
-  (make-actor
-   (lambda (self message)
+  (make-actor-with-address 'factorial
+   (lambda (self customer . message)
      (match message
-       ((n) (send-message self (list n 1)) 'sleep)
-       ((0 acc) (print acc) 'done)
-       ((n acc) (send-message self (list (- n 1) (* acc n))) 'sleep)))))
-
-;(send-message factorial '(5))
+       ((n) (send-message self customer n 1) 'sleep)
+       ((0 acc) (send-message customer acc) 'done)
+       ((n acc) (send-message self customer (- n 1) (* acc n)) 'sleep)))))
+
+(define println
+  (make-actor-with-address 'println
+   (lambda (self . message)
+     (apply print message)
+     'sleep)))
+
+(send-message factorial println 5)
+(send-message factorial println 7)
+(run)