From 8eec6741487bbc2199742f711974399bb937ce16 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 12 Dec 2004 20:29:52 +0000 Subject: [PATCH] Breakpointing that works much better with CGI and FCGI git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@136 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- railties/environments/development.rb | 9 +- railties/lib/breakpoint_client.rb | 172 ++++++++++++++------------- railties/lib/dispatcher.rb | 6 + 3 files changed, 99 insertions(+), 88 deletions(-) diff --git a/railties/environments/development.rb b/railties/environments/development.rb index 54720d3c1c..b8d4600759 100644 --- a/railties/environments/development.rb +++ b/railties/environments/development.rb @@ -2,11 +2,4 @@ ActionController::Base.consider_all_requests_local = true ActionController::Base.reload_dependencies = true ActiveRecord::Base.reload_associations = true -require 'breakpoint' -require 'irb/completion' -# Change the port (default: 42531) here in case you are -# on shared hosting. Note that you should set up a SSH -# tunnel when you want to connect from a different -# computer over the internet. See the documentation of -# Breakpoint.activate_drb for how to do that. -Breakpoint.activate_drb('druby://l​ocalhost:42531', nil, !defined?(FastCGI)) if $0.include?("dispatch") \ No newline at end of file +BREAKPOINT_SERVER_PORT = 42531 \ No newline at end of file diff --git a/railties/lib/breakpoint_client.rb b/railties/lib/breakpoint_client.rb index bdcad4cf3b..11e5bcaf9d 100644 --- a/railties/lib/breakpoint_client.rb +++ b/railties/lib/breakpoint_client.rb @@ -5,7 +5,8 @@ require 'timeout' options = { :ClientURI => nil, :ServerURI => "druby://localhost:42531", - :RetryDelay => 10 + :RetryDelay => 1, + :Verbose => false } ARGV.options do |opts| @@ -36,6 +37,11 @@ ARGV.options do |opts| "Default: druby://localhost:42531" ) { |options[:ServerURI]| } + opts.on("-v", "--verbose", + "Report all connections and disconnections", + "Default: false" + ) { |options[:Verbose]| } + opts.on("-R", "--retry-delay=delay", Integer, "Automatically try to reconnect to the", "server after delay seconds when the", @@ -56,97 +62,103 @@ end options[:ServerURI] = ARGV[0] if ARGV[0] -DRb.start_service(options[:ClientURI]) +puts "Waiting for initial breakpoint..." -begin - service = DRbObject.new(nil, options[:ServerURI]) +loop do + DRb.start_service(options[:ClientURI]) begin - timeout(10) { service.ping } - rescue Timeout::Error, DRb::DRbConnError - puts "", - " *** Breakpoint service didn't respond to ping request ***", - " This likely happened because of a misconfigured ACL (see the", - " documentation of Breakpoint.activate_drb, note that by default", - " you can only connect to a remote Breakpoint service via a SSH", - " tunnel), but might also be caused by an extremely slow connection.", - "" - raise - end + service = DRbObject.new(nil, options[:ServerURI]) - begin - service.register_eval_handler do |code| - result = eval(code, TOPLEVEL_BINDING) - result.extend(DRb::DRbUndumped) rescue nil - result + begin + timeout(10) { service.ping } + rescue Timeout::Error, DRb::DRbConnError + if options[:Verbose] + puts "", + " *** Breakpoint service didn't respond to ping request ***", + " This likely happened because of a misconfigured ACL (see the", + " documentation of Breakpoint.activate_drb, note that by default", + " you can only connect to a remote Breakpoint service via a SSH", + " tunnel), but might also be caused by an extremely slow connection.", + "" + end + raise end - service.register_collision_handler do - msg = [ - " *** Breakpoint service collision ***", - " Another Breakpoint service tried to use the", - " port already occupied by this one. It will", - " keep waiting until this Breakpoint service", - " is shut down.", - " ", - " If you are using the Breakpoint library for", - " debugging a Rails or other CGI application", - " this likely means that this Breakpoint", - " session belongs to an earlier, outdated", - " request and should be shut down via 'exit'." - ].join("\n") + begin + service.register_eval_handler do |code| + result = eval(code, TOPLEVEL_BINDING) + result.extend(DRb::DRbUndumped) rescue nil + result + end - if RUBY_PLATFORM["win"] then - # This sucks. Sorry, I'm not doing this because - # I like funky message boxes -- I need to do this - # because on Windows I have no way of displaying - # my notification via puts() when gets() is still - # being performed on STDIN. I have not found a - # better solution. - begin - require 'tk' - root = TkRoot.new { withdraw } - Tk.messageBox('message' => msg, 'type' => 'ok') - root.destroy - rescue Exception + service.register_collision_handler do + msg = [ + " *** Breakpoint service collision ***", + " Another Breakpoint service tried to use the", + " port already occupied by this one. It will", + " keep waiting until this Breakpoint service", + " is shut down.", + " ", + " If you are using the Breakpoint library for", + " debugging a Rails or other CGI application", + " this likely means that this Breakpoint", + " session belongs to an earlier, outdated", + " request and should be shut down via 'exit'." + ].join("\n") + + if RUBY_PLATFORM["win"] then + # This sucks. Sorry, I'm not doing this because + # I like funky message boxes -- I need to do this + # because on Windows I have no way of displaying + # my notification via puts() when gets() is still + # being performed on STDIN. I have not found a + # better solution. + begin + require 'tk' + root = TkRoot.new { withdraw } + Tk.messageBox('message' => msg, 'type' => 'ok') + root.destroy + rescue Exception + puts "", msg, "" + end + else puts "", msg, "" end - else - puts "", msg, "" - end - end - - service.register_handler do |workspace, message| - puts message - IRB.start(nil, nil, workspace) - puts "", "Resumed execution. Waiting for next breakpoint...", "" - end - - puts "Connection established. Waiting for breakpoint...", "" - - loop do - begin - service.ping - rescue DRb::DRbConnError => error - puts "Server exited. Exiting..." - exit! end - sleep(0.5) + service.register_handler do |workspace, message| + puts message + IRB.start(nil, nil, workspace) + puts "", "Resumed execution. Waiting for next breakpoint...", "" + end + + puts "Connection established. Waiting for breakpoint...", "" if options[:Verbose] + + loop do + begin + service.ping + rescue DRb::DRbConnError => error + puts "Server exited. Closing connection..." if options[:Verbose] + break + end + + sleep(0.5) + end + ensure + service.unregister_handler end - ensure - service.unregister_handler - end -rescue Exception => error - if options[:RetryDelay] > 0 then - puts "No connection to breakpoint service at #{options[:ServerURI]}:", - " (#{error.inspect})" - puts error.backtrace if $DEBUG - puts " Reconnecting in #{options[:RetryDelay]} seconds..." + rescue Exception => error + if options[:RetryDelay] > 0 then + puts "No connection to breakpoint service at #{options[:ServerURI]}:", " (#{error.inspect})" if options[:Verbose] + error.backtrace if $DEBUG + + puts " Reconnecting in #{options[:RetryDelay]} seconds..." if options[:Verbose] - sleep options[:RetryDelay] - retry - else - raise + sleep options[:RetryDelay] + retry + else + raise + end end end \ No newline at end of file diff --git a/railties/lib/dispatcher.rb b/railties/lib/dispatcher.rb index 4ecb9edd53..d30353dc7b 100644 --- a/railties/lib/dispatcher.rb +++ b/railties/lib/dispatcher.rb @@ -21,10 +21,14 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ +require 'breakpoint' + class Dispatcher DEFAULT_SESSION_OPTIONS = { :database_manager => CGI::Session::PStore, :prefix => "ruby_sess.", :session_path => "/" } def self.dispatch(cgi = CGI.new, session_options = DEFAULT_SESSION_OPTIONS) + Breakpoint.activate_drb("druby://localhost:#{BREAKPOINT_SERVER_PORT}", nil, !defined?(FastCGI)) if defined?(BREAKPOINT_SERVER_PORT) + begin request = ActionController::CgiRequest.new(cgi, session_options) response = ActionController::CgiResponse.new(cgi) @@ -44,6 +48,8 @@ class Dispatcher ActiveRecord::Base.reset_associations_loaded ActiveRecord::Base.reset_column_information_and_inheritable_attributes_for_all_subclasses end + + DRb.stop_service if defined?(BREAKPOINT_SERVER_PORT) end end