I always pass a control-channel into go loops, by which I can close it:

(defn looper [event-ch ctl-ch]
  (go-loop []
    (alt! event-ch ([event _] (handle-event event) (recur))
          ctl-ch   ([msg _] (assert (nil? msg))))))

This also makes it easy to funnel more control events then just end-of-life
into the loop.


2014-05-18 22:09 GMT+02:00 Dylan Butman <dbut...@gmail.com>:

> When working with channels and go blocks with nRepl, I often want to do
> something like this.
>
> (def events (event-generator))
> (go-loop []
>          (when-let [event (<! events)]
>            (handle-event event)
>            (recur)))
>
> Sometime later I want to stop listening, so I
>
> (close! events)
>
> This is fine, but I often find myself with a lot of boilerplate around go
> blocks where I'm constantly closing the channel, redefining it, and then
> re-evaluating the go-block just to try a different behavior. If you
> re-evaluate the go-block without closing the channel, you'll get duplicate
> actions. Additionally, if your channel drops out of scope, or you didn't
> set an exit condition on the go block (using while true or something
> similar), you can end up with indefinite operations that are impossible to
> kill without restarting the repl (and does this actually stop the code from
> continuing to execute somewhere in java)?
>
> I'm not very familiar with garbage collection, but is there some way to
> garbage collect blocks that have been re-evaluated? Does the treatment of
> re-evaluation depend on scope, ie. if you wrap it in a function, will it
> make a difference?
>
> I can imagine some function or macro that might close! and then re-create
> a channel everytime it's is called, maybe something like,
>
> (defn my-chan (atom (chan)))
> (defn test-chan []
>   (close! @my-chan)
>   (reset! my-chan (event-generator))
>   (go-loop []
>            (when-let [event (<! events)]
>              (handle-event event)
>              (recur))))
>
> But that doesn't really seem to reduce the complexity, since you'd have to
> define an atom for each of these types of functions.
>
> Thoughts?
>
> Best
> Dylan
>
>
>  --
> 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.

Reply via email to