Skip to content

Instantly share code, notes, and snippets.

@ashafa
Created March 8, 2010 15:29
Show Gist options
  • Save ashafa/325254 to your computer and use it in GitHub Desktop.
Save ashafa/325254 to your computer and use it in GitHub Desktop.
(defmulti watch-changes
"Provided a database (database meta, java.net.URL, or database name) and a callback, watches
for changes to the database and executes the given callback (takes one argument) on every change
to a document in the given database, using the meta of the changed document as the only
argument of the callback."
database-arg-type)
(defn- watch-changes-handler
[url-str agnt]
(if (h/success? agnt)
(loop [lines (io/read-lines (h/stream agnt))]
(if-let [watched-db (@watched-databases url-str)]
(when (not (empty? lines))
(future
(let [line (first lines)]
(try
((:callback watched-db) (binding [json-read/*json-keyword-keys* true]
(json-read/read-json line)))
(catch Exception e
(dosync
(if (@watched-databases url-str)
(alter watched-databases update-in [url-str :last-error]
(constantly {:execption e :time (java.util.Date.) :data line}))))))))
(recur (rest lines)))))))
(defmethod watch-changes :name
[db-name callback & options]
(apply watch-changes (assoc @*defaults* :name db-name) callback options))
(defmethod watch-changes :url
[url callback & options]
(apply watch-changes (utils/url->db-meta url) callback options))
(defmethod watch-changes :meta
[db-meta callback & options]
(let [url-str (utils/db-meta->url db-meta)
options-map (merge (first options) {:heartbeat 30 :feed "continuous"})]
(dosync
(if (contains? @watched-databases url-str)
(alter watched-databases update-in [url-str :callback] (constantly callback))
(alter watched-databases assoc url-str
{:http-agent (h/http-agent
(str url-str "/_changes" (utils/map-to-query-str options-map false))
:method "GET"
:handler (partial watch-changes-handler url-str))
:callback callback})))
db-meta))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment