-
-
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?