Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/tags/rel_1-2-1/railties/lib/breakpoint_client.rb

Revision 4502, 5.5 kB (checked in by ulysses, 2 years ago)

Remove opts.on { |options[:option_name] } style hash assignment. Closes #4440.

Line 
1 require 'breakpoint'
2 require 'optparse'
3 require 'timeout'
4
5 Options = {
6   :ClientURI  => nil,
7   :ServerURI  => "druby://localhost:42531",
8   :RetryDelay => 2,
9   :Permanent  => true,
10   :Verbose    => false
11 }
12
13 ARGV.options do |opts|
14   script_name = File.basename($0)
15   opts.banner = [
16     "Usage: ruby #{script_name} [Options] [server uri]",
17     "",
18     "This tool lets you connect to a breakpoint service ",
19     "which was started via Breakpoint.activate_drb.",
20     "",
21     "The server uri defaults to druby://localhost:42531"
22   ].join("\n")
23
24   opts.separator ""
25
26   opts.on("-c", "--client-uri=uri",
27     "Run the client on the specified uri.",
28     "This can be used to specify the port",
29     "that the client uses to allow for back",
30     "connections from the server.",
31     "Default: Find a good URI automatically.",
32     "Example: -c druby://localhost:12345"
33   ) { |v| Options[:ClientURI] = v }
34
35   opts.on("-s", "--server-uri=uri",
36     "Connect to the server specified at the",
37     "specified uri.",
38     "Default: druby://localhost:42531"
39   ) { |v| Options[:ServerURI] = v }
40
41   opts.on("-R", "--retry-delay=delay", Integer,
42     "Automatically try to reconnect to the",
43     "server after delay seconds when the",
44     "connection failed or timed out.",
45     "A value of 0 disables automatical",
46     "reconnecting completely.",
47     "Default: 10"
48   ) { |v| Options[:RetryDelay] = v }
49
50   opts.on("-P", "--[no-]permanent",
51     "Run the breakpoint client in permanent mode.",
52     "This means that the client will keep continue",
53     "running even after the server has closed the",
54     "connection. Useful for example in Rails."
55   ) { |v| Options[:Permanent] = v }
56
57   opts.on("-V", "--[no-]verbose",
58     "Run the breakpoint client in verbose mode.",
59     "Will produce more messages, for example between",
60     "individual breakpoints. This might help in seeing",
61     "that the breakpoint client is still alive, but adds",
62     "quite a bit of clutter."
63   ) { |v| Options[:Verbose] = v }
64
65   opts.separator ""
66
67   opts.on("-h", "--help",
68     "Show this help message."
69   ) { puts opts; exit }
70   opts.on("-v", "--version",
71     "Display the version information."
72   ) do
73     id = %q$Id: breakpoint_client.rb 91 2005-02-04 22:34:08Z flgr $
74     puts id.sub("Id: ", "")
75     puts "(Breakpoint::Version = #{Breakpoint::Version})"
76     exit
77   end
78
79   opts.parse!
80 end
81
82 Options[:ServerURI] = ARGV[0] if ARGV[0]
83
84 module Handlers #:nodoc:
85   extend self
86
87   def breakpoint_handler(workspace, message)
88     puts message
89     IRB.start(nil, nil, workspace)
90
91     puts ""
92     if Options[:Verbose] then
93       puts "Resumed execution. Waiting for next breakpoint...", ""
94     end
95   end
96
97   def eval_handler(code)
98     result = eval(code, TOPLEVEL_BINDING)
99     if result then
100       DRbObject.new(result)
101     else
102       result
103     end
104   end
105
106   def collision_handler()
107     msg = [
108       "  *** Breakpoint service collision ***",
109       "  Another Breakpoint service tried to use the",
110       "  port already occupied by this one. It will",
111       "  keep waiting until this Breakpoint service",
112       "  is shut down.",
113       "  ",
114       "  If you are using the Breakpoint library for",
115       "  debugging a Rails or other CGI application",
116       "  this likely means that this Breakpoint",
117       "  session belongs to an earlier, outdated",
118       "  request and should be shut down via 'exit'."
119     ].join("\n")
120
121     if RUBY_PLATFORM["win"] then
122       # This sucks. Sorry, I'm not doing this because
123       # I like funky message boxes -- I need to do this
124       # because on Windows I have no way of displaying
125       # my notification via puts() when gets() is still
126       # being performed on STDIN. I have not found a
127       # better solution.
128       begin
129         require 'tk'
130         root = TkRoot.new { withdraw }
131         Tk.messageBox('message' => msg, 'type' => 'ok')
132         root.destroy
133       rescue Exception
134         puts "", msg, ""
135       end
136     else
137       puts "", msg, ""
138     end
139   end
140 end
141
142 # Used for checking whether we are currently in the reconnecting loop.
143 reconnecting = false
144
145 loop do
146   DRb.start_service(Options[:ClientURI])
147
148   begin
149     service = DRbObject.new(nil, Options[:ServerURI])
150
151     begin
152       ehandler = Handlers.method(:eval_handler)
153       chandler = Handlers.method(:collision_handler)
154       handler = Handlers.method(:breakpoint_handler)
155       service.eval_handler = ehandler
156       service.collision_handler = chandler
157       service.handler = handler
158
159       reconnecting = false
160       if Options[:Verbose] then
161         puts "Connection established. Waiting for breakpoint...", ""
162       end
163
164       loop do
165         begin
166           service.ping
167         rescue DRb::DRbConnError => error
168           puts "Server exited. Closing connection...", ""
169           exit! unless Options[:Permanent]
170           break
171         end
172
173         sleep(0.5)
174       end
175     ensure
176       service.eval_handler = nil
177       service.collision_handler = nil
178       service.handler = nil
179     end
180   rescue Exception => error
181     if Options[:RetryDelay] > 0 then
182       if not reconnecting then
183         reconnecting = true
184         puts "No connection to breakpoint service at #{Options[:ServerURI]} " +
185            "(#{error.class})"
186         puts error.backtrace if $DEBUG
187         puts "Tries to connect will be made every #{Options[:RetryDelay]} seconds..."
188       end
189
190       sleep Options[:RetryDelay]
191       retry
192     else
193       raise
194     end
195   end
196 end
Note: See TracBrowser for help on using the browser.