-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First draft IVar-Future-Promise-Probe unification #176
Conversation
Does this link to some discussion? What's the background and motivation for this? |
It relates to #139, just put a #139 (comment) there. |
58e9054
to
6570f13
Compare
Love it! |
At first glance there seem to be some great ideas here. Unfortuntely I only have my iPad with me and won't be able to pull the code until I return home. I apologize for not being able to take a more thorough look right now. |
77362cf
to
3d25ac1
Compare
another set of improvements
|
Latest commit allows to chain the futures into acyclic graph (branches are created with # if head of the tree is not constructed with #future but with #delay it does not start execute,
# it's triggered later by calling wait or value on any of the dependent futures or the delay
# itself
three = (head = delay { 1 }).then { |v| v.succ }.then(&:succ)
four = three.then_delay(&:succ)
# evaluates only up to three, four is left unevaluated
p three.value # 3
p four.complete? # false
# until #value is called on four
p four.value # 4
# futures hidden behind two delays trigger evaluation of both
double_delay = delay { 1 }.then_delay(&:succ)
p double_delay.value # 2 head = future { 1 }
branch1 = head.then(&:succ).then(&:succ)
branch2 = head.then(&:succ).then_delay(&:succ)
result = Future.join(branch1, branch2).then { |b1, b2| b1 + b2 }
sleep 0.1
p branch1.completed?, branch2.completed? # true, false
# force evaluation of whole graph
p result.value # 6 |
3b877db
to
cacb3d8
Compare
There are usage examples at the end of the file, I forgot to mention that. Thanks @iNecas. |
It'll also work nicely with actors. actor.ask(:msg).then { |result| p result } # no blocking |
require 'jruby' | ||
|
||
# roughly more than 2x faster | ||
class JavaSynchronizedObject |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I really like this new synchronized object. Being able to wait on a mutex is a great feature, and I always like it when we can optimize on JRuby.
Has there been any discussion around chaining futures where one of the futures' value might be a future itself? Contrived example: future { future { 1 } }.then { |v| v + 3 }.value Where Future#then is analogous to Scala's Future.map, something like a Future#flat_then could be analogous to Scala's Future.flatMap. Of course, duplicating the various chaining methods with #flat_* versions seems somewhat messy. Perhaps a Future#flatten which would operate kind of like Future.join, but would join together (conceptually) a future and it's value (if the value ends up resolving to another future). # Example
future { future { 1 } }.flatten.then { |v| v + 1 }.value Thoughts? |
I'm all for |
@brasten good point @obrok I think @brasten meant: id Hm, so to sum it up and to make the api consistent I think I add |
Hm, I'm not sure That said, they can maybe coexist? |
IIRC bangs aren't supposed to signify destructive but alternative, so then!
|
@obrok ah I see, thanks. I've looked at Scala Future API and the names are driven a lot by Scala's for comprehension and the way how it unrolls. I'll try to push something later. |
- untangle callback into methods for better readability - promise tree starting with delay can be now also triggered by calling wait or value on any of the children - better inspectability - track what blocks what - better to_s and inspect support
- Adds #chain_delay, #then_delay, #rescue_delay which are same as #chain, #then, #rescue but are not evaluated automatically but only when requested by #value. - Restructure class hierarchy. Only one Future with Multiple Promise implementations which are hidden to the user. Provides better encapsulation. - Delay is now implemented as a Promise descendant.
adding Scala's flatMap
supports all, any, flattening
Hi, f = ConcurrentNext.future { ConcurrentNext.future { 1 } }.flat.then(&:succ)
expect(f.value).to eq 2 which corresponds with ConcurrentNext.
future { sleep 0.1; 1 }.
schedule(0.1).
then { |v| v + 1 }.
value # returns 2 in 0.2 sec
f = ConcurrentNext.
future { 1 }.
then(&:succ). # evaluates up to here
delay.
then(&:succ) # this is lazy evaluated when firstly requested by #value
f.value # returns 3
f1 = ConcurrentNext.future {1}
f2 = ConcurrentNext.future {2}
ConcurrentNext.all(f1, f2).then { |v1, v2| v1+v2 }.value # => 3
ConcurrentNext.any(f1, f2).value # => 1 or 2 depends on which one finishes first |
I've suggested in #139 that we close this PR and release 1.0 with the existing APIs. Please continue the discussion there. |
merged to #274 |
Not ready for merge. Opening discussion. Compatibility layer is totally missing for now.