                               )))
 	      )))
 
-(defn exception-listener [write-lock-ch v {:keys [internal-error-ch]}]
+(defn exception-listener
   "Returns a GenericFutureListener instance
    that on completion checks the Future, if any exception
    an error is sent to the error-ch"
+  [write-lock-ch v {:keys [internal-error-ch]}]
   (reify GenericFutureListener
     (operationComplete [this f]
        ;(go (>! write-lock-ch 1)) ;release write lock

				     (timeout timeout-ms)]))))
		    
  ([{:keys [error-ch]}]
  "Reads from the error-ch and blocks if no data is available"
    (if error-ch (<!! error-ch))))



(defn- do-write [^Client client write-lock-ch ^bytes v close-after-write {:keys [internal-error-ch] :as conf}]
  "Writes to the channel, this operation is non blocking and a exception listener is added to the write's ChannelFuture
   to send any errors to the internal-error-ch"
   (let [^Channel channel (-> client ^ChannelFuture (:channel-f) ^Channel (.channel))]
     (if (.isOpen channel)
	     (let [ch-f (-> channel ^ChannelFuture (.writeAndFlush v) (.addListener ^ChannelFutureListener (exception-listener write-lock-ch v conf)))]

                                       )))))))
           

(defn write!
  "Writes and blocks if the write-ch is full"
  [client v]
  (if (-> client ^ChannelFuture (:channel-f) ^Channel (.channel) (.isOpen))
    (>!! (:write-ch client) v)
    (throw (RuntimeException. "Client closed"))))
  

(defn read!
  "Reads from the read-ch and blocks if no data is available"
  ([{:keys [read-ch]} timeout-ms]
    (first 
      (alts!!
		     [read-ch
		     (timeout timeout-ms)])))
  ([{:keys [read-ch]}]
  (<!! read-ch)))


(defn read-error 
   "Reads from the error-ch and blocks if no data is available"
   ([{:keys [error-ch]} timeout-ms]
     (if error-ch
		    (first 
