Permalink
Browse files

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
  • Loading branch information...
1 parent c9cc73d commit 8eec6741487bbc2199742f711974399bb937ce16 @dhh dhh committed Dec 12, 2004
Showing with 98 additions and 87 deletions.
  1. +1 −8 railties/environments/development.rb
  2. +91 −79 railties/lib/breakpoint_client.rb
  3. +6 −0 railties/lib/dispatcher.rb
@@ -2,11 +2,4 @@
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")
+BREAKPOINT_SERVER_PORT = 42531
@@ -5,7 +5,8 @@
options = {
:ClientURI => nil,
:ServerURI => "druby://localhost:42531",
- :RetryDelay => 10
+ :RetryDelay => 1,
+ :Verbose => false
}
ARGV.options do |opts|
@@ -36,6 +37,11 @@
"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 @@
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
-
- begin
- service.register_eval_handler do |code|
- result = eval(code, TOPLEVEL_BINDING)
- result.extend(DRb::DRbUndumped) rescue nil
- result
+ service = DRbObject.new(nil, options[:ServerURI])
+
+ 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")
-
- 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
+ begin
+ service.register_eval_handler do |code|
+ result = eval(code, TOPLEVEL_BINDING)
+ result.extend(DRb::DRbUndumped) rescue nil
+ result
+ 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")
+
+ 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
+ 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...", ""
+ puts "Connection established. Waiting for breakpoint...", "" if options[:Verbose]
- loop do
- begin
- service.ping
- rescue DRb::DRbConnError => error
- puts "Server exited. Exiting..."
- exit!
- end
+ loop do
+ begin
+ service.ping
+ rescue DRb::DRbConnError => error
+ puts "Server exited. Closing connection..." if options[:Verbose]
+ break
+ end
- sleep(0.5)
+ 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
@@ -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 @@ def self.dispatch(cgi = CGI.new, session_options = DEFAULT_SESSION_OPTIONS)
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

0 comments on commit 8eec674

Please sign in to comment.