Skip to content
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

Make force work in conditions for futures, not only promises. #27

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

raxoft
Copy link

@raxoft raxoft commented May 17, 2016

The Future#force should return the resulting value, not the promise. Otherwise things like

   puts "true" if future{ true }.force
   puts "false" if future{ false }.force
   puts "nil" if future{ nil }.force

do not work as expected (currently all evaluate to true). I believe it should work consistently with promises:

   puts "true" if promise{ true }.force
   puts "false" if promise{ false }.force
   puts "nil" if promise{ nil }.force

The change above should achieve this. However note it may change how the marshalling works with regard to futures, as the special marshalling handling found in Promise becomes bypassed. You may want to review this aspect yourself.

@bhuga
Copy link
Owner

bhuga commented May 17, 2016

This seems valid at first glance. Can you create a test that demonstrates the problem?

@coveralls
Copy link

coveralls commented May 17, 2016

Coverage Status

Coverage increased (+0.8%) to 100.0% when pulling 6b945e5 on raxoft:patch-1 into 2ee99b6 on bhuga:master.

@raxoft
Copy link
Author

raxoft commented May 17, 2016

The test case is the example above - it prints all three lines in case of futures, while only the first line for promises. Should be trivial to convert to the appropriate assert/expect/should/whatever.

I would need it for construct like this which I sometimes use for running things in parallel:

   something.map{ |x| future{ do_something_with x } }.map{ |x| x.force }

It works almost fine now, except that nil/false results are not properly handled in the resulting array, depending on how they are use.

@bhuga
Copy link
Owner

bhuga commented May 17, 2016

The test case is the example above

I'd need to see these added to the specs in the code. Note that travis is failing.

something.map{ |x| future{ do_something_with x } }.map{ |x| x.force }

Can I ask why you're doing this? The point of future is that they start running immediately. The second map here isn't doing anything that the futures haven't already started doing as soon as they were created.

The Future#__force__ should return the resulting value, not the promise. Otherwise things like
``` ruby
   puts "true" if future{ true }.force
   puts "false" if future{ false }.force
   puts "nil" if future{ nil }.force
```
do not work as expected (currently all evaluate to true). I believe it should work consistently with promises:
``` ruby
   puts "true" if promise{ true }.force
   puts "false" if promise{ false }.force
   puts "nil" if promise{ nil }.force
```
The change above should achieve this. However note it may change how the marshalling works with regard to futures, as the special marshalling handling found in Promise becomes bypassed. You may want to review this aspect yourself.
@coveralls
Copy link

coveralls commented May 18, 2016

Coverage Status

Coverage increased (+0.8%) to 100.0% when pulling 85aa5fe on raxoft:patch-1 into 2ee99b6 on bhuga:master.

@coveralls
Copy link

coveralls commented May 18, 2016

Coverage Status

Coverage increased (+0.8%) to 100.0% when pulling 175897b on raxoft:patch-1 into 2ee99b6 on bhuga:master.

@raxoft
Copy link
Author

raxoft commented May 18, 2016

I have added the tests to the specs.

As for the travis failing, that's because the shared spec tests for compatibility with Marshal. However, Marshalling of futures doesn't work anyway (and didn't before), as Future class lacks the _load method and Marshal.load fails because of that. So I adjusted the spec accordingly. The alternative would be adding proper Marshalling support to Future class itself, basically cloning the functionality from Promise class.

As for the map{ |x| x.force } question: the first map runs some asynchronous requests which involve networking communication, the second map uses force to ensure that all the requests finish and any possible exceptions are raised at that point, within controlled context, before any further processing is done.

@raxoft
Copy link
Author

raxoft commented May 18, 2016

Hmm, the travis tests now pass for everything but JRuby, but checking the log it seems travis has problems running bundler under JRuby, rather than the tests themselves failing. I can't see how this can be fixed other than trying running the tests on travis again later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants