When a let binding gets used across a blocking operation, the binding leaks out of the let.
`
(async/go-loop []
(let [msg (async/<! in-ch)]
(if msg
(let [stuff (vec (range 1 100000))]
(async/<! out-ch stuff)
(println stuff)
(recur))
(recur))))
`
The {{stuff}} binding gets stuck into the the state-machine state. This persists across the {{recur}}, until the binding is next encountered.
(In our case, a few GBs had accumuled by that time.)
Ideally, the fields in the state that represent local variables would be nulled when the variables go out of scope.