Future/Promise and not using threads

272 views
Skip to first unread message

David Pollak

unread,
May 29, 2013, 5:29:09 PM5/29/13
to clo...@googlegroups.com
Howdy,

I'm looking at using Future/Promise to be thread-friendly in some code.

Background... Lift has Futures (or LAFuture... yeah... go ahead make fun of the name... pronounce it with a French accent)... with Lift futures, one can do:

future.foreach(v => /* do something with the value */)

If the Future has been realized (or satisfied in Lift parlance), then the function executes in the current thread. If the Future has not been realized, the function is executed on a thread-pool thread once the Future has been realized. This means that we don't have to consume threads waiting for a Future to finish its work... and we can continue a computation on the thread-pool thread once the future has finished.

Is there a way to get a code block to execute when a Future (or Promise) is realized?

As an adjunct to that question... in Lift, we have fast-fail Futures. You can pass in List[Future[Box[X]]] and get a Future[Box[List[X]]]... but the Box will be Empty if any of the Futures fail (return an Empty Box or a Failure Box). The advantage is that if you fork off a bunch of requests to external systems you can fail-fast with your uber request if any of the systems fail.

Is there a similar facility in Clojure.

Thanks for your time and your help?

David


--
Telegram, Simply Beautiful CMS https://telegr.am
Lift, the simply functional web framework http://liftweb.net

Mark Engelberg

unread,
May 30, 2013, 5:09:54 AM5/30/13
to clo...@googlegroups.com
According to this article, Clojure does not yet have this facility:
http://java.dzone.com/articles/promises-and-futures-clojure

This is something that is being worked on and discussed, though:
http://dev.clojure.org/display/design/Promises
https://groups.google.com/forum/#!topic/clojure-dev/7BKQi9nWwAw/discussion
http://dev.clojure.org/display/design/Async+blocks

I've been hearing a lot about Tellman's lamina library as a rich Clojure toolset for working with asynchronicity.  I haven't had a need for it myself, but you might want to check it out and see if it has relevance to what you want to do.

Gary Trakhman

unread,
May 30, 2013, 5:14:18 AM5/30/13
to clo...@googlegroups.com
Maybe an easy solution: wrap the first future in another future that blocking-derefs, then performs your extra computation?  Do an extra 'realized?' check for the optimization you mention.  That would still consume threads in the case that it's not realized, but I think it gets you what you want.



--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Gary Trakhman

unread,
May 30, 2013, 5:17:31 AM5/30/13
to clo...@googlegroups.com
by the second future, I mean an instance of http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html , which just has to conform to the interface, and doesn't actually have to execute on a different thread.  Clojure's 'future' function returns an instance of one of these that uses the unbounded agent thread-pool, but you would be free to return one using reify or something.

David Pollak

unread,
May 30, 2013, 9:09:02 AM5/30/13
to clo...@googlegroups.com
Okay... I wrote my own:


One can register for on-done and on-fail. I'll work on adding fail-fast and also map (so one can transform the future and execute code when the transformed future has been realized/delivered/finished).

Thanks for your help!

Paul deGrandis

unread,
May 30, 2013, 3:36:13 PM5/30/13
to clo...@googlegroups.com
I'm not entirely sure what you're trying to accomplish in a larger context, but perhaps you're looking for something like this?

(delay (deref (future (and (Thread/sleep 2000) (+ 1 2)))))

... or maybe you want just `delay`

Cheers,
Paul

David Pollak

unread,
May 30, 2013, 3:46:24 PM5/30/13
to clo...@googlegroups.com
Paul,

Thanks... but I want the opposite of delay.

Basically, I do not want to consume a thread waiting for a Future to be satisfied. I want to continue a computation on a different thread once the Future/Promise is satisfied. Why?

Think of a web app that's serving either a long poll or a web socket. Basically, you don't want to consume a thread waiting for some computation to take place. Rather, you want the computation to take place and then for the computation of sending the result to continue/resume once the computation has completed. Futures/Promises are excellent vehicles for this, especially when functions close over local scope and most of the local scope is persistant) and we use them extensively in Lift-land.

I will move a lot of the stuff I've developed in Lift-land over to Clojure as many of the constructs will, I believe, play as well on Clojure as they do on Scala.

Thanks,

David

David Nolen

unread,
May 30, 2013, 3:51:27 PM5/30/13
to clojure
You might find this work in progress interesting then: http://github.com/clojure/core.async

Paul deGrandis

unread,
May 30, 2013, 3:54:07 PM5/30/13
to clo...@googlegroups.com
Oh!  I see, you want promises with callbacks (which you want to be futures).
Once a promise is delivered, you want to kick off a future (in Clojure, futures consume a thread from the thread pool to do their work).

It's been discussed before: https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/7BKQi9nWwAw

You may find a more elegant solution in the upcoming async work: https://github.com/clojure/core.async

As previously stated you can use some mix of promise, delay, future, map, pmap, and reducers (much as you have already done).

If you're just looking for a completely async solution right now, I'd suggest lamina: https://github.com/ztellman/lamina

Paul
Reply all
Reply to author
Forward
0 new messages