I'm confused on the thread issue. Don't futures run from the agent thread 
pool? So they don't really create a thread?

Also found climatecorp's claypoole library, which has a 'future' call that 
works with a thread pool, further confusing me. Not sure how that's 
different from the agent thread pool.

On Saturday, December 6, 2014 1:16:56 PM UTC-8, juan.facorro wrote:
>
> Hi Brian,
>
> I had the same requirement while building an application, it included a 
> GUI and I wanted to perform some actions only after the user was done 
> editing some text. I also first implemented a solution using an atom, 
> Thread/sleep and a future. It didn't seem right though, since I was 
> creating a bunch of threads all the time, so I tried an approach with the 
> tools core.async provides and the result was the following:
>
> (defn timeout-channel
>   "Creates a channel and a go block that takes from it. The go block keeps 
> an internal status with two possible values, `:wait` and `:receive`. 
> In ':wait' status, execution is blocked until there's a value available in the
> channel, it then enters the ':receive' status, until the timeout wins. 
> Returns the channel where events need to be pushed."
>   [timeout-ms f]
>   (let [c (async/chan)]
>     (async/go-loop [status   :wait
>                     args     nil]
>       (condp = status
>         :wait
>           (recur :receive (async/<! c))
>         :receive
>           (let [[_ ch] (async/alts! [c (async/timeout timeout-ms)])]
>             (if (= ch c)
>               (recur :receive args)
>               (do
>                 (async/thread (if (sequential? args) (apply f args) (f args)))
>                 (recur :wait nil)))))) 
>
>     c)) 
>
> Signalling the go block to terminate when the event source is no longer 
> available is missing, but that simple enough to implement. Maybe this is 
> something you can use as a starter point.
>
> Hope it helps,
>
> Juan
>
>
>
> On Monday, December 1, 2014 6:37:56 PM UTC-3, Brian Craft wrote:
>>
>> I have need to perform an action when a series of events is quiet for 
>> some period. That is, if one event arrives an action is queued to execute 
>> after some timeout. If a second event arrives the timeout is reset, and 
>> so-forth.
>>
>> The following code seems to work, however I'm wondering if calling 
>> 'future' from 'swap!' is a bad idea (side effecting), and if there's a 
>> better way.
>>
>> (defn queue-with-delay [period func]
>>   (let [f (atom nil)]
>>     (fn []
>>       (when @f
>>         (future-cancel @f))
>>       (swap! f (fn [_] (future (Thread/sleep period) (func)))))))
>>
>>
>> Use like
>>
>> (def event (queue-with-delay 2000 #(println "running")))
>> (event)
>> (event)
>> (event)  ; pause 2 sec
>> "running"
>>
>>
>>
>>

-- 
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