This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-11-21
Channels
- # admin-announcements (14)
- # aws (27)
- # beginners (10)
- # boot (152)
- # cljsrn (3)
- # clojure (93)
- # clojure-hk (4)
- # clojure-russia (35)
- # clojure-switzerland (1)
- # clojurecup (1)
- # clojurescript (146)
- # core-async (23)
- # cursive (2)
- # devcards (1)
- # editors (1)
- # hoplon (28)
- # jobs-rus (4)
- # ldnclj (3)
- # leiningen (3)
- # luminus (2)
- # off-topic (4)
- # om (174)
- # re-frame (1)
- # slack-help (5)
for example if I bind a dynamic var with binding
and then send a value across a channel, will the binding go with it?
@bsima: my experience with ClojureScript (don’t know about Clojure): I avoid using binding directly within go block code. It behaved unpredictably. But wrapping it in a function called from go block fixed my issues and behaved as expected. Binding is active while function sits on a callstack (javascript has only a single thread).
@darwin, hm, thanks for the report. My plan will just be to wrap the thing I'm passing through the channel in a map that includes the value to which I want the binding to be set. At the other end of the channel, I'll have a function that actually makes the binding if necessary. I'm working in clojure and don't wanna mess with the complexity of multithreaded dynamic bindings
fwiw I'm implementing a restarts system like in this talk https://www.youtube.com/watch?v=zp0OEDcAro0 pretty awesome talk
@ghadi really? I mean I would think that dynamic scope wouldn't be maintained across threads, but I'm not familiar with the theoretical foundations in this area
Hm okay then. Could also be that my implementation was a unique case. I also had a thread pool and a component involved, but I'll try and reproduce the binding bug tomorrow or Monday with a minimal example
@darwin: that was actually passed onto me by @michaeldrogalis while we were talking about his dire library. He says he prefers this restart technique over his dire technique nowadays, and I have to agree
(defn persist!
"Persist a thing via a core.async channel. The optional argument err will be
bound to the *persist-error* restart."
([component thing]
(let [ch (:channel component)]
(>!! ch thing)))
([component thing err]
(binding [*persist-error* err]
(persist! component thing))))
At the other end of that channel I have this:
(defn- persist-impl
"Implementation of the persister. Simply spits to `tmp-<timestamp>'. If no
file descriptor fd is given, then a unique filename is generates.
Fail: calls *persist-error*
Success: calls *success*
Restart: *persist-retry*, lexically bound to persist-impl."
([content]
(let [t (time/now)
fd (format "tmp-%s-%s.txt" t (uuid))]
(persist-impl fd content)))
([fd content]
(spit fd content)
(if (persisted? fd)
(*success*)
(binding [*persist-retry*
(fn [_ _] (persist-impl fd content))]
(*persist-error* "Persist failure!" {:file fd})))))