2016-07-10 16:33:16 +00:00
|
|
|
#lang syndicate/actor
|
2016-02-29 02:33:53 +00:00
|
|
|
;; Toy file system, based on the example in the ESOP2016 submission.
|
|
|
|
;; Low-level implementation.
|
|
|
|
|
2016-07-31 16:17:12 +00:00
|
|
|
(require/activate "fs-shell.rkt")
|
|
|
|
(require/activate "fs-protocol.rkt")
|
|
|
|
|
2016-04-01 23:53:46 +00:00
|
|
|
(require (only-in syndicate [assert core:assert]))
|
2016-02-29 02:33:53 +00:00
|
|
|
(require racket/set)
|
|
|
|
|
|
|
|
(define (file-system-event-handler e files)
|
2016-03-01 21:56:58 +00:00
|
|
|
(match-event e
|
2016-02-29 02:33:53 +00:00
|
|
|
[(? patch? p)
|
|
|
|
(transition files
|
2016-02-29 14:15:29 +00:00
|
|
|
(for-trie/list [((observe (file $name _)) (patch-added p))]
|
2016-02-29 14:21:05 +00:00
|
|
|
(printf "At least one reader exists for ~v\n" name)
|
|
|
|
(define initial-content (hash-ref files name #f))
|
|
|
|
(spawn (file-observation-event-handler name)
|
|
|
|
initial-content
|
|
|
|
(patch-seq (core:assert (file name initial-content))
|
|
|
|
(sub (observe (file name ?)))
|
|
|
|
(sub (save (file name ?)))
|
|
|
|
(sub (delete name))))))]
|
2016-02-29 02:33:53 +00:00
|
|
|
[(message (save (file name new-content)))
|
|
|
|
(transition (hash-set files name new-content) '())]
|
|
|
|
[(message (delete name))
|
2016-03-01 21:56:58 +00:00
|
|
|
(transition (hash-remove files name) '())]))
|
2016-02-29 02:33:53 +00:00
|
|
|
|
|
|
|
(spawn file-system-event-handler
|
|
|
|
(hash)
|
|
|
|
(patch-seq (sub (observe (file ? ?)))
|
|
|
|
(sub (save (file ? ?)))
|
|
|
|
(sub (delete ?))))
|
|
|
|
|
2016-03-01 22:00:57 +00:00
|
|
|
(define (update-file old-content name new-content)
|
|
|
|
(transition new-content
|
|
|
|
(patch-seq (retract (file name old-content))
|
|
|
|
(core:assert (file name new-content)))))
|
|
|
|
|
|
|
|
(define ((file-observation-event-handler name) e content)
|
|
|
|
(match-event e
|
|
|
|
[(? patch? p)
|
|
|
|
(when (not (set-empty? (project-assertions (patch-removed p) (observe (file (?!) ?)))))
|
|
|
|
(printf "No remaining readers exist for ~v\n" name)
|
|
|
|
(quit))]
|
|
|
|
[(message (save (file (== name) new-content)))
|
|
|
|
(update-file content name new-content)]
|
|
|
|
[(message (delete (== name)))
|
|
|
|
(update-file content name #f)]))
|