         listener
         (let [new-l (ServerSocketChannel/open)]
           (and listener (.close listener))
-          (doto new-l (.bind (InetSocketAddress. req-port))))))
+          (doto new-l
+            (.configureBlocking false)
+            (.bind (InetSocketAddress. req-port))))))
     nil))
 
 (defn combined-config-watcher [prefix]

  (let [[address port] (str/split a #":")]
    {:address address :port (Integer/parseInt port)}))

(defn s->millepoch-time [s]
  (.getTimeInMillis (clojure.instant/read-instant-calendar s)))

(defn millepoch-time-now []
  (.getTime (java.util.Date.)))

(defn update-backends [backends config]
  (let [existing (keys backends)
        wanted (keys (:backends config))
        unwanted (clojure.set/difference (set existing) (set wanted))]
    (run! close! (map #(:chan (get backends %)) unwanted))
    (reduce (fn [m [n v]]
              (let [a (parse-address (:listen-address v))]
                (assoc m
                       n
                       (or ;(get backends n)
                           (assoc v
                                  :name n
                                  :chan (backend-chan (:address a) (:port a))
                                  :last-seen-at-ms
                                  (if-let [ls (:last-seen-at v)]
                                    (s->millepoch-time ls)

            Selector SelectionKey])
  (:require [merlion.etcd :as etcd]
            [clojure.string :as str]
            [clojure.test :as test :refer [deftest testing is]]
            [clojure.java.io :as io]
            [clojure.pprint :refer [pprint]]
            [clojure.set :as set]
            [clojure.core.async :as async
             :refer [<! <!! go chan >! close! alts!]]))

(defn s->millepoch-time [s]
  (.getTimeInMillis (clojure.instant/read-instant-calendar s)))

(defn millepoch-time-now []
  (.getTime (java.util.Date.)))


(defn server-socket
  "Opens a ServerSocketChannel listening on the specified TCP `port` then
