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

rescue Exception in Futures #431

Merged
merged 2 commits into from Sep 30, 2015
Merged

Conversation

pitr-ch
Copy link
Member

@pitr-ch pitr-ch commented Sep 30, 2015

follow up of #430

@pitr-ch pitr-ch added the enhancement Adding features, adding tests, improving documentation. label Sep 30, 2015
@pitr-ch pitr-ch self-assigned this Sep 30, 2015
@pitr-ch pitr-ch added this to the 1.0.0 Release milestone Sep 30, 2015
complete_with Future::Failed.new(error)
rescue Exception => error
complete_with Future::Failed.new(error)
log(ERROR, 'Edge::Future', error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this change the return value of this method when rescuing Exception? It appears to no longer return a Future. I'm not sure of the ramifications.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, it would break the documented behaviour, it would break CompletableFuture#evaluate_to. Fixing and merging.

@hobodave
Copy link
Contributor

FYI, we're using this in our code, and it's working. So, once my comment above is addressed (if needed) this is good to merge. 👍

@jdantonio
Copy link
Member

@hobodave Do you mind if I ask what project you are using this in? I 💚 hearing about projects that use this gem!

pitr-ch pushed a commit that referenced this pull request Sep 30, 2015
rescue Exception in Futures
@pitr-ch pitr-ch merged commit 1b24e0b into ruby-concurrency:master Sep 30, 2015
@hobodave
Copy link
Contributor

@jdantonio I'm using it in a REST API we're building internally. The API is basically serving as an aggregator of several other internal APIs. So, one request to our application may need to make dozens (or hundreds in rare cases) of concurrent requests to downstream APIs to return a response in a timely fashion.

@hobodave
Copy link
Contributor

@jdantonio Any chance you could build 1.0.0pre4/0.2.0pre4 incorporating this fix? We're unable to bundle/use the gem when using the git/ref syntax in the Gemfile.

Thanks!

@jdantonio
Copy link
Member

Certainly. I'll try to get that out in the next day or two. Will that be soon enough? (I needed to get the pre3 update out ASAP for Rails, which is why I didn't wait for this PR.)

@pitr-ch
Copy link
Member Author

pitr-ch commented Sep 30, 2015

what is the problem with git/ref ?

@hobodave
Copy link
Contributor

@jdantonio That's fine.

@pitr-ch It's a really bizarre error. I thought it might be my local environment, but another developer on my team is having the same issue on his local machine. Here's the details:

# Gemfile
gem 'concurrent-ruby', git: 'https://github.com/ruby-concurrency/concurrent-ruby.git', ref: '1b24e0bd48e7bdd0b6b1c98820d2f470296df755'
gem 'concurrent-ruby-edge', git: 'https://github.com/ruby-concurrency/concurrent-ruby.git', ref: '1b24e0bd48e7bdd0b6b1c98820d2f470296df755'

When attempting to run rspec via console:

$ RAILS_ENV=test bundle exec rspec -cfd spec/
NotImplementedError: NotImplementedError
                             synchronize at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/synchronization/abstract_lockable_object.rb:15
                              initialize at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/utility/at_exit.rb:15
                     <module:Concurrent> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/utility/at_exit.rb:96
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/utility/at_exit.rb:4
                                 require at org/jruby/RubyKernel.java:939
                         block in (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                 require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                 require at org/jruby/RubyKernel.java:939
                         block in (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/executor/abstract_executor_service.rb:4
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                 require at org/jruby/RubyKernel.java:939
                        block in require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/executor/immediate_executor.rb:2
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                                 require at org/jruby/RubyKernel.java:939
                        block in require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                 require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/delay.rb:3
                                 require at org/jruby/RubyKernel.java:939
                         block in (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                 require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                 require at org/jruby/RubyKernel.java:939
                         block in (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent/configuration.rb:2
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                 require at org/jruby/RubyKernel.java:939
                        block in require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bundler/gems/concurrent-ruby-1b24e0bd48e7/lib/concurrent.rb:4
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                                    load at org/jruby/RubyKernel.java:957
                        block in require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                         load_dependency at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232
                                 require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                         block in (root) at /Users/davida/Developer/deal-management-api/lib/global.rb:2
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                                 require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                        block in require at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247
                                    each at org/jruby/RubyArray.java:1560
                         block in (root) at /Users/davida/Developer/deal-management-api/config/initializers/00_autoload.rb:1
                           instance_exec at org/jruby/RubyBasicObject.java:1670
                                  (root) at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:1
                           block in load at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241
                           block in load at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241
        block in load_config_initializer at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/engine.rb:648
  each_strongly_connected_component_from at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:429
                     block in instrument at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/activesupport-4.1.4/lib/active_support/notifications.rb:161
                                    each at org/jruby/RubyArray.java:1560
                                    call at org/jruby/RubyMethod.java:127
                 load_config_initializer at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/engine.rb:647
                                  Engine at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/engine.rb:612
                                  Engine at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/engine.rb:611
                                     run at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/initializable.rb:30
                        run_initializers at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/initializable.rb:55
                             public_send at org/jruby/RubyKernel.java:1823
                              tsort_each at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:226
                                   <top> at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:348
                                 require at org/jruby/RubyKernel.java:939
                                   <top> at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:347
                                 require at org/jruby/RubyKernel.java:939
                                   <top> at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:345
                                    load at org/jruby/RubyKernel.java:957
                     block in tsort_each at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:224
                                    each at org/jruby/RubyArray.java:1560
                              tsort_each at /Users/davida/.rvm/rubies/jruby-9.0.1.0/lib/ruby/stdlib/tsort.rb:203
                        run_initializers at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/initializable.rb:54
                             initialize! at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/application.rb:300
                          method_missing at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/gems/railties-4.1.4/lib/rails/railtie.rb:194
                                  (root) at /Users/davida/Developer/deal-management-api/config/environment.rb:5
                                   <top> at /Users/davida/Developer/deal-management-api/spec/spec_helper.rb:1
                                    load at org/jruby/RubyKernel.java:957
                                  <eval> at /Users/davida/Developer/deal-management-api/spec/spec_helper.rb:5
                                    eval at org/jruby/RubyKernel.java:978
                                   <top> at /Users/davida/.rvm/gems/jruby-9.0.1.0@deal-management-api/bin/jruby_executable_hooks:15

This only happens when I point directly at a ref. Strangely, if I point directly at my local copy:

# Gemfile
gem 'concurrent-ruby', path: '/Users/davida/Developer/concurrent-ruby'
gem 'concurrent-ruby-edge', path: '/Users/davida/Developer/concurrent-ruby'

This works just fine.

Should I create an issue for this?

@jdantonio
Copy link
Member

@hobodave Please open an issue, if you don't mind. I've taken a cursory look at the code and I think the problem is the compiled Java extensions. If you compiled the Java extensions in your local repo then they will load when you point your Gemfile to the local path, but they won't ever load when you reference the git repo (since we don't check the compiled Java code into git). If I'm correct you can verify by deleting the compiled code from your local repo and see if the error surfaces.

@jdantonio
Copy link
Member

@pitr-ch I think the problem is on line 9 of object.rb. When on JRuby we assume that the Java extensions are compiled and loaded. On line 45 of native_extension_loaded.rb we silently fail if the Java extensions do not load, so our assumption is not valid.

Contrast this to how we load the C extensions on line 84 of atomic_boolean.rb. In the latter case we use when defined?(CAtomicBoolean) to ensure that the extensions have been loaded.

One way to handle this would be to allow the load error in native_extension_loader.rb to bubble up. I'm not a big fan of this approach. A JRuby user should be able to use the pure-Ruby gem. We should probably log something in native_extension_loader.rb rather than fail silently.

Another approach would be to use defined? in object.rb, like this:

    ObjectImplementation = case
                           when Concurrent.on_cruby?
                             MriObject
                           when defined? JRubyObject
                             JRubyObject
                           when Concurrent.on_rbx?
                             RbxObject
                           else
                             warn 'Possibly unsupported Ruby implementation'
                             MriObject
                           end

I'll create a PR with these changes then we can move the discussion over there.

@jdantonio
Copy link
Member

See PR #434. Let's move discussion of the load error to that thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Adding features, adding tests, improving documentation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants