A few thoughts on ways to improve this code:
Using agents and go blocks in the same code is a bit odd. If you need a queue plus a process, just do something like this:
(defn faux-agent [c]
(go (loop []
(when-let [msg (<! c)]
...do something...
(recur)))))
This go block will automatically terminate once the input channel is closed. Now you have code that is almost like an agent, but works well with channels (including back-pressure).
Also, instead of having a public req channel and a response channel, consider using higher-order channels. Yes, you can send channels via channels. So instead of having a request look like this:
(>! req-chan :req)
do something like this:
(>! req-chan [file-name my-response-channel])
(<! my-response-channel)
This allows many processes to make requests and your code will end up a little easier to reason about.
Just some thoughts.
Timothy Baldridge