Skip to content

Instantly share code, notes, and snippets.

@film42
Last active August 29, 2015 14:09
Show Gist options
  • Save film42/159377a9474026a8542f to your computer and use it in GitHub Desktop.
Save film42/159377a9474026a8542f to your computer and use it in GitHub Desktop.
(ns hn.realtime
(:require [cheshire.core :refer :all]))
(def base-url "https://hacker-news.firebaseio.com/v0")
(defn get-updates
"Return response regardless of condition"
[] (parse-string (slurp (str base-url "/updates.json")) true))
(defprotocol IPoller
"Poller interface for polling an API request or other observable function"
(start [_] "Start the agent poller")
(stop [_] "Stop the agent poller")
(register [_ cb] "Register a callback with the poller"))
(defn poller
"Run a poller loop for some agent using some observable function `f` and some delay time in seconds"
[f delay]
(let [cond-var (atom true)
state (atom {})
callbacks (atom [])]
;; Create new poller object
(reify IPoller
;; Start the poller
(start [_]
(send-off
(agent {})
(fn [_] (while @cond-var
(let [resp (f)]
;; Alert registered callbacks of messages
(if-not (= resp @state)
(do (reset! state resp)
(doseq [cb @callbacks]
(cb @state)))
;; Else: do nothing
[]))
;; Wait for delay duration
(Thread/sleep (* delay 1000))))))
;; Stop the poller from running
(stop [_]
(reset! cond-var false)
true)
;; Register a callback
(register [_ cb] (swap! callbacks conj cb)))))
(defn poll-updates []
;; We can rest for 30-seconds because that's about
;; how long the API interval is +/- 5-seconds.
(poller get-updates 30))
;
; Usage:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Create the poller object
(def poller (poll-updates))
;; Register a callback
(defn poller-cb [msg]
(println (:items msg)))
(register poller poller-cb)
;; Start the Poller (on a seperate thread)
(start poller)
;; Now the you see `poller-cb` print the items:
[8615397 8615238 8609412 8616925 8584538]
[8616404 8615889 8616966 8616566 8614943 8614518]
[8616968 8615546 8616573 8615889 8616966 8616598 8616764 8616918 8614736]
[8583747 8615669 8616966 8616144 8614933]
[8614942 8616481 8616014 8615508 8616686 8616738]
[8616896 8616581 8616069 8611492 8613307]
;; Now stop the poller
(stop poller)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment