#lang syndicate ;; Explore use of sandboxes etc for being an "operating system" (require racket/match) (require racket/sandbox) (define (program-boot-actions modspec) (parameterize ((sandbox-input (current-input-port)) (sandbox-output (current-output-port))) (define e (make-evaluator 'racket/base)) (define ns (call-in-sandbox-context e current-namespace)) (for [(syndicate-modspec (in-list (list 'syndicate/actor 'syndicate/canonicalize 'syndicate/core 'syndicate/treap 'syndicate/trie 'syndicate/tset)))] (namespace-attach-module (current-namespace) syndicate-modspec ns)) (e `(require (submod ,modspec syndicate-main))) (e `(activate!)))) (struct running-app (id) #:prefab) ;; assertion (struct kill-app (id) #:prefab) ;; message (struct named-account (name balance) #:prefab) ;; assertion (define (run-bank-account name) (struct account (balance) #:prefab) (dataspace (define id (symbol->string (gensym 'app))) (printf "Starting app ~a\n" id) (schedule-action! (program-boot-actions 'syndicate/examples/actor/bank-account)) (spawn (assert (outbound (running-app id))) (on (message (inbound (kill-app id))) (printf "Received signal for app ~a\n" id) (quit-dataspace!)) (during (account $balance) (assert (outbound (named-account name balance))))))) (run-bank-account 'a) (run-bank-account 'b) (run-bank-account 'c) (spawn (on (asserted (named-account $name $balance)) (printf "Named account balance ~a = ~a\n" name balance))) (spawn (define/query-set running-apps (running-app $id) id) (begin/dataflow (printf "Running apps: ~v\n" (running-apps)))) (let () (local-require racket/port) (define e (read-bytes-line-evt (current-input-port) 'any)) (spawn (stop-when (message (inbound (external-event e (list (? eof-object? _)))))) (on (message (inbound (external-event e (list (? bytes? $bs))))) (define app-id (bytes->string/utf-8 bs)) (printf "Killing ~a\n" app-id) (send! (kill-app app-id)))))