robin.fnl (1707B)
1 (local { : directory? : symlink } (require :anoia.fs)) 2 (local { : assoc : system } (require :anoia)) 3 (local inotify (require :inotify)) 4 5 (fn parse-args [args] 6 (match args 7 ["-p" proxy & rest] (assoc (parse-args rest) :proxy proxy) 8 backends { : backends } 9 _ nil)) 10 11 (fn %% [fmt ...] (string.format fmt ...)) 12 13 (fn start-service [service] 14 (let [(ok msg) (pcall system (%% "s6-rc-up-tree %q" service))] 15 (when (not ok) (print msg)) 16 ok)) 17 18 (fn stop-service [service] 19 (let [(ok msg) (pcall system (%% "s6-rc -b -d change %q" service))] 20 (when (not ok) (print msg)) 21 ok)) 22 23 (fn watch-fsevents [directory-name] 24 (doto (inotify.init) 25 (: :addwatch directory-name 26 inotify.IN_CREATE 27 inotify.IN_MOVE 28 inotify.IN_DELETE 29 inotify.IN_DELETE_SELF 30 inotify.IN_MOVED_FROM 31 inotify.IN_MOVED_TO 32 inotify.IN_CLOSE_WRITE))) 33 34 (fn round-robin [els] 35 (var i -1) 36 (fn [] 37 (set i (% (+ 1 i) (# els))) 38 (. els (+ 1 i)))) 39 40 (fn run [] 41 (let [{ : proxy : backends } (parse-args arg)] 42 (each [s (round-robin backends)] 43 (print "ROBIN starting " s) 44 (when (start-service s) 45 (let [outputs-dir (.. "/run/services/outputs/" s)] 46 (print "ROBIN started " s "expecting outputs in " outputs-dir) 47 (with-open [watcher (watch-fsevents outputs-dir)] 48 (symlink outputs-dir "active") 49 (start-service proxy) 50 (while (directory? outputs-dir) 51 (print :ROBIN (watcher:read)))))) 52 ;; service failed to start, or started and finished 53 (print "ROBIN finished " s "stopping proxy") 54 (stop-service proxy) 55 (stop-service s) 56 (os.remove "active") 57 ))) 58 59 { : run }