When an object is built from a map, aggregating mixins is a trivial operation. But when a mixin needs to be closed, it is better to have a common mechanism to manage a stack of the close functions of all the aggregated mixins than to depend on application logic to do so. Case in point, I'd like to use an actor mixin or an alternative async channel mixin when composing a database. The async channel mixin will require a close but the actor mixin will not. So I developed the closer mixin to handle the calls to both the async channel and db file close functions. The database will only know the closer's do-close method. And it is the responsibility of the async channel and the db file mixins to register their close functions with the closer mixin.
My inspiration is Stuart Sierra's component library <https://github.com/stuartsierra/component>. But I am not handling dependencies per say, only managing a stack of close functions. And the "components" are only functions and atoms added to a common map structure, not records or deftypes. The result is a very lightweight pattern for components. The closer code itself is a lock-free mixin that gets added to the common map as needed when the on-close method is called. For more information, see Closer <https://github.com/laforge49/aatree/wiki/Closer>. (ns aatree.closer (:require [clojure.tools.logging :as log])) (set! *warn-on-reflection* true) (defn on-close [f opts] (let [fsa (:closer-fsa opts)] (if fsa (do (swap! fsa (fn [fs] (if fs (conj fs f) (atom (list f))))) opts) (assoc opts :closer-fsa (atom (list f)))))) (defn- do-closer [fs opts] (when fs (try ((first fs) opts) (catch Exception e (log/warn e "exception on close"))) (recur (next fs) opts))) (defn do-close [opts] (let [fsa (:closer-fsa opts)] (if fsa (let [fs @fsa] (if fs (if (compare-and-set! fsa fs nil) (do-closer fs opts) (recur opts))))))) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.