While an agent is probably what you want, you should not use it like that. I'm not sure how you can get a failed state with the given code, but here's how I would do it.
First off, the agent is only meant for logging, so let's keep it on that job alone. In log-entry, replace the (dosync ...) with: (defn add-entry [log entry] (send log conj entry)) You can keep the receive and transmit functions unchanged, but the dotimes block should be changed by something along the lines of: (let [t1 (Thread. (fn [] (dotimes [_ 10] (transmit async-log writer socket request)))) t2 (Thread. (fn [] (dotimes [_ 10] (receive async-log reader socket))))] (.start t1) (.start t2) (.join t1) (.join t2)) dosync is for refs (the ones created with (ref ...), not "references" in the general sense), and delimits a transaction in which all refs are updated atomically (so refs are mainly useful when you want to update multiple mutable references "at the same time"). send-off is only useful if you're doing a blocking operation within the function that handles the agent. I must admit I have no idea how the given code can yield inconsistent results. Does anyone know if agents, like refs, call the given functions speculatively? It would seem strange if an agent did not serialize the functions you send it. On Thursday, 15 May 2014, Dylan Gleason <dgleason8...@gmail.com> wrote: > I have a TCP socket connection in which I need to process several requests > and conj each request and it's corresponding response to a vector for > logging purposes. I need to transmit and receive via two asynchronous > threads, where a transmit function is responsible for sending requests > and a receive function is responsible for receiving responses from a > server. > > My understanding is that for asynchronous transmission, I need to use > agent in Clojure to accomplish this. However, I also need to ensure > serial access to the vector, since both threads are trying to modify it at > any given time. > > I tried to get something working, but my agent ends up in a failed state > after making a few requests and processing a few responses. Below is the > code showing what I am attempting to do. If anyone could give me some > guidance, it would be greatly appreciated. > > ;; the shared resource > > > (def async-log (agent [])) > > > ;; I thought this needed to be synchronized for serial access, so I > used > > ;; dosync, but I am not sure if this is right. In any case, it doesn't > > ;; seem to make a difference > > > (defn add-entry > > [coll entry] > > (dosync (conj coll entry))) > > > ;; transmit function > > > (defn transmit > > [log writer socket request] > > (let [request (request->String request socket) > > bytes-out (request->bytes request) > > length (count bytes-out)] > > (.writeShort writer length) > > (.write writer bytes-out 0 length) > > (add-entry log request))) > > > ;; Receive function > > > (defn receive > > [log reader socket] > > (let [length (read-length reader) > > bytes-in (byte-array request/max-message-size)] > > (.read reader bytes-in 0 length) > > (add-entry log (to-string bytes-in)))) > > > ;; process each request, n times > > > (defn process-requests > > [request socket iters] > > (with-open [reader (DataInputStream. (.getInputStream socket)) > > writer (DataOutputStream. (.getOutputStream socket))] > > (dotimes [x iters] > > (send-off async-log transmit writer socket request) > > (send-off async-log receive reader socket) > > (Thread/sleep 50)))) > > -- > 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. > -- 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.