1 #+TITLE: Concurrent Propagator System
2 #+OPTIONS: num:nil ^:nil
7 :tangle: src/propagator.clj
12 #^{:author "Eric Schulte",
14 :doc "Simple concurrent propagator system."}
16 (:use clojure.contrib.repl-utils
17 clojure.contrib.duck-streams))
19 (defmacro cell "Define a new cell."
21 `(def ~name (agent ~state)))
25 (defmacro propagator "Define a new propagator."
26 [name in-cells out-cells & body]
28 (defn ~(with-meta name
30 :in-cells in-cells :out-cells out-cells))
32 (doseq [cell# ~in-cells] (add-neighbor cell# ~name))
35 (defmacro run-propagator
36 "Run a propagator, first collect the most recent values from all
37 cells associated with the propagator, then evaluate."
39 `(let [output-val# (apply ~propagator (map deref (:in-cells ^#'~propagator)))
40 output-cells# (:out-cells ^#'~propagator)]
41 (append-spit "/home/eschulte/Desktop/spitoon"
42 (format "results in %S\n" output-val#))
43 (append-spit "/home/eschulte/Desktop/spitoon"
44 (format "sending to %S\n" output-cells#))
45 (dosync [cell# output-cells#]
46 (append-spit "/home/eschulte/Desktop/spitoon"
47 (format "sending %S to %S\n" output-val# output-cells#))
48 (send cell# (fn [_#] output-val#)))))
50 (defmacro add-neighbor "Add a neighbor to the given cell."
55 (fn [_#] (dosync (run-propagator ~neighbor)) true))
60 ** look at mutable data stores
61 - http://clojure.org/agents
62 - http://clojure.org/atoms
63 - http://clojure.org/refs
65 most definitely will use agents, functions to set their values are
66 applied to them with send (or send-off if potentially I/O bound), they
67 support validators, and they can be set to run actions (i.e. alert
68 propagators) as part of their update cycle.
70 ** design to permit distribution across multiple machines
71 it should be possible to wrap these mutable items including
72 - network connections from other machines
73 - hardware (timers, I/O devices, etc...)
75 in cells, so that the propagator system remains "pure"
78 This probably mentioned a request for advice from the mailing list or
79 from the #clojure group.