-
-
Save lmarburger/994107 to your computer and use it in GitHub Desktop.
| require 'rubygems' | |
| require 'eventmachine' | |
| require 'fiber' | |
| EM.error_handler { |e| p "EM.error_handler: #{ e.message }" } | |
| run(lambda do |env| | |
| case env['PATH_INFO'] | |
| ### | |
| # Hits EM.error_handler | |
| # | |
| # $ bundle exec thin start | |
| # >> Using rack adapter | |
| # >> Thin web server (v1.2.11 codename Bat-Shit Crazy) | |
| # >> Maximum connections set to 1024 | |
| # >> Listening on 0.0.0.0:3000, CTRL+C to stop | |
| # "yielding" | |
| # "throwing" | |
| # "done sleeping" | |
| # "EM.error_handler: die" | |
| when '/sleep' | |
| Fiber.new do | |
| fiber = Fiber.current | |
| EM::Timer.new(1) { p 'done sleeping'; fiber.resume } | |
| p 'yielding' | |
| Fiber.yield | |
| raise 'die' | |
| end.resume | |
| p 'throwing' | |
| throw :async | |
| ### | |
| # Crashes app server using eventmachine 0.12.10 and em-http-request 0.3.0. | |
| # EM.error_handler catches the exception using em-http-request master. | |
| # | |
| # $ bundle exec thin start | |
| # >> Using rack adapter | |
| # >> Thin web server (v1.2.11 codename Bat-Shit Crazy) | |
| # >> Maximum connections set to 1024 | |
| # >> Listening on 0.0.0.0:3000, CTRL+C to stop | |
| # "yielding" | |
| # "throwing" | |
| # "resuming" | |
| # /Users/Larry/Sites/pollex/config.ru:57:in `block (3 levels) in <main>': die (RuntimeError) | |
| when '/http' | |
| require 'em-http' | |
| Fiber.new do | |
| f = Fiber.current | |
| http = EM::HttpRequest.new('http://getcloudapp.com').get | |
| http.callback { p 'resuming'; f.resume(http) } | |
| p 'yielding' | |
| Fiber.yield | |
| raise 'die' | |
| end.resume | |
| p 'throwing' | |
| throw :async | |
| ### | |
| # Crashes app server using eventmachine 0.12.10 and em-http-request 0.3.0. | |
| # EM.error_handler catches the exception using em-http-request master. | |
| # | |
| # $ bundle exec thin start | |
| # >> Using rack adapter | |
| # >> Thin web server (v1.2.11 codename Bat-Shit Crazy) | |
| # >> Maximum connections set to 1024 | |
| # >> Listening on 0.0.0.0:3000, CTRL+C to stop | |
| # "throwing" | |
| # "http.callback" | |
| # /Users/Larry/Sites/pollex/config.ru:79:in `block (3 levels) in <main>': die (RuntimeError) | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/em/deferrable.rb:134:in `call' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/em/deferrable.rb:134:in `set_deferred_status' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/em/deferrable.rb:173:in `succeed' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/em-http-request-0.3.0/lib/em-http/client.rb:307:in `unbind' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/eventmachine.rb:1417:in `event_callback' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/lib/thin/backends/base.rb:61:in `start' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/lib/thin/server.rb:159:in `start' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/lib/thin/controllers/controller.rb:86:in `start' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/lib/thin/runner.rb:185:in `run_command' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/lib/thin/runner.rb:151:in `run!' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/gems/thin-1.2.11/bin/thin:6:in `<top (required)>' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/bin/thin:19:in `load' | |
| # from /Users/Larry/.rvm/gems/ruby-1.9.2-p180@pollex/bin/thin:19:in `<main>' | |
| when '/http-no-fiber' | |
| require 'em-http' | |
| http = EM::HttpRequest.new('http://getcloudapp.com').get | |
| p "EM.reactor_thread?: #{ EM.reactor_thread? }" | |
| http.callback do | |
| p 'http.callback' | |
| p "EM.reactor_thread?: #{ EM.reactor_thread? }" | |
| raise 'die' | |
| end | |
| p 'throwing' | |
| throw :async | |
| when '/defer' | |
| operation = lambda { p 'operation' } | |
| callback = lambda { |result| raise 'callback' } | |
| EM.defer operation, callback | |
| p 'throwing' | |
| throw :async | |
| ### | |
| # Caught by thin, maybe? | |
| # | |
| # $ bundle exec thin start | |
| # >> Using rack adapter | |
| # >> Thin web server (v1.2.11 codename Bat-Shit Crazy) | |
| # >> Maximum connections set to 1024 | |
| # >> Listening on 0.0.0.0:3000, CTRL+C to stop | |
| # !! Unexpected error while processing request: die | |
| when '/die' | |
| raise 'die' | |
| ### | |
| # Crashes app server as expected. | |
| # | |
| # $ bundle exec thin start | |
| # >> Using rack adapter | |
| # >> Thin web server (v1.2.11 codename Bat-Shit Crazy) | |
| # >> Maximum connections set to 1024 | |
| # >> Listening on 0.0.0.0:3000, CTRL+C to stop | |
| # "throwing" | |
| # /Users/Larry/Sites/pollex/config.ru:94:in `block (3 levels) in <main>': thread (RuntimeError) | |
| when '/thread' | |
| Thread.new do | |
| sleep 1 | |
| raise 'thread' | |
| end | |
| p 'throwing' | |
| throw :async | |
| end | |
| end) |
| source :gemcutter | |
| gem 'em-http-request', :git => 'https://github.com/igrigorik/em-http-request.git' | |
| gem 'thin' |
| GIT | |
| remote: https://github.com/igrigorik/em-http-request.git | |
| revision: ddfb713b29570d2f93713f619d94e5960ea8f627 | |
| specs: | |
| em-http-request (1.0.0.beta.3) | |
| addressable (>= 2.2.3) | |
| em-socksify | |
| eventmachine (>= 1.0.0.beta.3) | |
| http_parser.rb (>= 0.5.1) | |
| GEM | |
| remote: http://rubygems.org/ | |
| specs: | |
| addressable (2.2.6) | |
| daemons (1.1.3) | |
| em-socksify (0.1.0) | |
| eventmachine | |
| eventmachine (1.0.0.beta.3) | |
| http_parser.rb (0.5.1) | |
| rack (1.3.0) | |
| thin (1.2.11) | |
| daemons (>= 1.0.9) | |
| eventmachine (>= 0.12.6) | |
| rack (>= 1.0.0) | |
| PLATFORMS | |
| ruby | |
| DEPENDENCIES | |
| em-http-request! | |
| thin |
Thanks for the suggestion! No dice, though. I'm looking through em-http-request and eventmachine to see if they're doing anything with threads.
Yeah, I realize now it was a bad guess on my part. Threads should be involved here. I'm stumped. Ping Ilya Grigorik on Twitter (igrigorik). He will know.
I updated the gist to add a test case for raising an exception in a thread with Thread.abort_on_exception = true. The server dies in the same way as /http.
Looks like it has nothing to do with fibers. I added /http-no-fiber that raises an exception in HttpClient#callback and it also takes down thin.
Larry, can you try building eventmachine from master? When I run your example, I get:
"throwing"
"http.callback"
"Thread.abort_on_exception: true"
"EM.error_handler: die"
As in, it doesn't blow up.
Fantastic! Thin crashed out after only upgrading to eventmachine master but using it along with em-http-request master works like a champ.
Awesome. :)
My guess is that it is because the exception is being raised in a thread. What happens if you put this line at the top of file?