rails 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rails might be problematic. Click here for more details.

Files changed (46) hide show
  1. data/CHANGELOG +59 -10
  2. data/Rakefile +23 -11
  3. data/bin/console +6 -5
  4. data/bin/console_sandbox +0 -6
  5. data/bin/listener +86 -0
  6. data/bin/profiler +27 -10
  7. data/bin/rails +3 -1
  8. data/bin/runner +24 -0
  9. data/bin/server +1 -0
  10. data/bin/tracker +69 -0
  11. data/configs/database.yml +3 -0
  12. data/dispatches/dispatch.fcgi +22 -25
  13. data/dispatches/gateway.cgi +97 -0
  14. data/environments/development.rb +2 -0
  15. data/environments/environment.rb +1 -0
  16. data/environments/test.rb +2 -0
  17. data/fresh_rakefile +9 -4
  18. data/helpers/test_helper.rb +16 -5
  19. data/html/404.html +2 -0
  20. data/html/500.html +2 -0
  21. data/html/index.html +3 -0
  22. data/html/javascripts/controls.js +261 -0
  23. data/html/javascripts/dragdrop.js +476 -0
  24. data/html/javascripts/effects.js +570 -0
  25. data/html/javascripts/prototype.js +633 -371
  26. data/lib/console_sandbox.rb +6 -0
  27. data/lib/dispatcher.rb +13 -11
  28. data/lib/fcgi_handler.rb +166 -0
  29. data/lib/rails_generator/generators/applications/app/app_generator.rb +16 -12
  30. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +2 -2
  31. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +3 -1
  32. data/lib/rails_generator/generators/components/migration/USAGE +14 -0
  33. data/lib/rails_generator/generators/components/migration/migration_generator.rb +9 -0
  34. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -0
  35. data/lib/rails_generator/generators/components/model/model_generator.rb +1 -1
  36. data/lib/rails_generator/generators/components/scaffold/USAGE +1 -1
  37. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +11 -11
  38. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +38 -20
  39. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +2 -0
  40. data/lib/rails_generator/generators/components/scaffold/templates/style.css +22 -1
  41. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +2 -2
  42. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +5 -5
  43. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +1 -1
  44. data/lib/rubyprof_ext.rb +35 -0
  45. data/lib/webrick_server.rb +84 -43
  46. metadata +22 -8
data/CHANGELOG CHANGED
@@ -1,3 +1,52 @@
1
+ *SVN*
2
+
3
+ * Changed the default logging level in config/environment.rb to INFO for production (so SQL statements won't be logged)
4
+
5
+ * Added migration generator: ./script/generate migration add_system_settings
6
+
7
+ * Added "migrate" as rake task to execute all the pending migrations from db/migrate
8
+
9
+ * Fixed that model generator would make fixtures plural, even if ActiveRecord::Base.pluralize_table_names was false #1185 [Marcel Molina]
10
+
11
+ * Added a DOCTYPE of HTML transitional to the HTML files generated by Rails #1124 [Michael Koziarski]
12
+
13
+ * SIGTERM also gracefully exits dispatch.fcgi. Ignore SIGUSR1 on Windows.
14
+
15
+ * Add the option to manually manage garbage collection in the FastCGI dispatcher. Set the number of requests between GC runs in your public/dispatch.fcgi [skaes@web.de]
16
+
17
+ * Allow dynamic application reloading for dispatch.fcgi processes by sending a SIGHUP. If the process is currently handling a request, the request will be allowed to complete first. This allows production fcgi's to be reloaded without having to restart them.
18
+
19
+ * RailsFCGIHandler (dispatch.fcgi) no longer tries to explicitly flush $stdout (CgiProcess#out always calls flush)
20
+
21
+ * Fixed rakefile actions against PostgreSQL when the password is all numeric #1462 [michael@schubert.cx]
22
+
23
+ * ActionMailer::Base subclasses are reloaded with the other rails components #1262
24
+
25
+ * Made the WEBrick adapter not use a mutex around action performance if ActionController::Base.allow_concurrency is true (default is false)
26
+
27
+ * Fixed that mailer generator generated fixtures/plural while units expected fixtures/singular #1457 [Scott Barron]
28
+
29
+ * Added a 'whiny nil' that's aim to ensure that when users pass nil to methods where that isn't appropriate, instead of NoMethodError? and the name of some method used by the framework users will see a message explaining what type of object was expected. Only active in test and development environments by default #1209 [Michael Koziarski]
30
+
31
+ * Fixed the test_helper.rb to be safe for requiring controllers from multiple spots, like app/controllers/article_controller.rb and app/controllers/admin/article_controller.rb, without reloading the environment twice #1390 [Nicholas Seckar]
32
+
33
+ * Fixed Webrick to escape + characters in URL's the same way that lighttpd and apache do #1397 [Nicholas Seckar]
34
+
35
+ * Added -e/--environment option to script/runner #1408 [fbeausoleil@ftml.net]
36
+
37
+ * Modernize the scaffold generator to use the simplified render and test methods and to change style from @params["id"] to params[:id]. #1367
38
+
39
+ * Added graceful exit from pressing CTRL-C during the run of the rails command #1150 [Caleb Tennis]
40
+
41
+ * Allow graceful exits for dispatch.fcgi processes by sending a SIGUSR1. If the process is currently handling a request, the request will be allowed to complete and then will terminate itself. If a request is not being handled, the process is terminated immediately (via #exit). This basically works like restart graceful on Apache. [Jamis Buck]
42
+
43
+ * Made dispatch.fcgi more robust by catching fluke errors and retrying unless its a permanent condition. [Jamis Buck]
44
+
45
+ * Added console --profile for profiling an IRB session #1154 [Jeremy Kemper]
46
+
47
+ * Changed console_sandbox into console --sandbox #1154 [Jeremy Kemper]
48
+
49
+
1
50
  *0.12.1* (20th April, 2005)
2
51
 
3
52
  * Upgraded to Active Record 1.10.1, Action Pack 1.8.1, Action Mailer 0.9.1, Action Web Service 0.7.1
@@ -132,17 +181,17 @@
132
181
  Views : components/list/items/show.rhtml
133
182
 
134
183
 
135
- * Added --sandbox option to script/console that'll roll back all changes made to the database when you quit #672 [bitsweat]
184
+ * Added --sandbox option to script/console that'll roll back all changes made to the database when you quit #672 [Jeremy Kemper]
136
185
 
137
- * Added 'recent' as a rake target that'll run tests for files that changed in the last 10 minutes #612 [bitsweat]
186
+ * Added 'recent' as a rake target that'll run tests for files that changed in the last 10 minutes #612 [Jeremy Kemper]
138
187
 
139
- * Changed script/console to default to development environment and drop --no-inspect #650 [bitsweat]
188
+ * Changed script/console to default to development environment and drop --no-inspect #650 [Jeremy Kemper]
140
189
 
141
- * Added that the 'fixture :posts' syntax can be used for has_and_belongs_to_many fixtures where a model doesn't exist #572 [bitsweat]
190
+ * Added that the 'fixture :posts' syntax can be used for has_and_belongs_to_many fixtures where a model doesn't exist #572 [Jeremy Kemper]
142
191
 
143
192
  * Added that running test_units and test_functional now performs the clone_structure_to_test as well #566 [rasputnik]
144
193
 
145
- * Added new generator framework that informs about its doings on generation and enables updating and destruction of generated artifacts. See the new script/destroy and script/update for more details #487 [bitsweat]
194
+ * Added new generator framework that informs about its doings on generation and enables updating and destruction of generated artifacts. See the new script/destroy and script/update for more details #487 [Jeremy Kemper]
146
195
 
147
196
  * Added Action Web Service as a new add-on framework for Action Pack [Leon Bredt]
148
197
 
@@ -346,7 +395,7 @@
346
395
  Nothing changes inside the files themselves.
347
396
 
348
397
 
349
- * Fixed a few references in the tests generated by new_mailer [bitsweat]
398
+ * Fixed a few references in the tests generated by new_mailer [Jeremy Kemper]
350
399
 
351
400
  * Added support for mocks in testing with test/mocks
352
401
 
@@ -355,7 +404,7 @@
355
404
 
356
405
  *0.8.5* (9)
357
406
 
358
- * Made dev-util available to all tests, so you can insert breakpoints in any test case to get an IRB prompt at that point [bitsweat]:
407
+ * Made dev-util available to all tests, so you can insert breakpoints in any test case to get an IRB prompt at that point [Jeremy Kemper]:
359
408
 
360
409
  def test_complex_stuff
361
410
  @david.projects << @new_project
@@ -364,11 +413,11 @@
364
413
 
365
414
  You need to install dev-utils yourself for this to work ("gem install dev-util").
366
415
 
367
- * Added shared generator behavior so future upgrades should be possible without manually copying over files [bitsweat]
416
+ * Added shared generator behavior so future upgrades should be possible without manually copying over files [Jeremy Kemper]
368
417
 
369
- * Added the new helper style to both controller and helper templates [bitsweat]
418
+ * Added the new helper style to both controller and helper templates [Jeremy Kemper]
370
419
 
371
- * Added new_crud generator for creating a model and controller at the same time with explicit scaffolding [bitsweat]
420
+ * Added new_crud generator for creating a model and controller at the same time with explicit scaffolding [Jeremy Kemper]
372
421
 
373
422
  * Added configuration of Test::Unit::TestCase.fixture_path to test_helper to concide with the new AR fixtures style
374
423
 
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require 'rbconfig'
9
9
 
10
10
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
11
11
  PKG_NAME = 'rails'
12
- PKG_VERSION = '0.12.1' + PKG_BUILD
12
+ PKG_VERSION = '0.13.0' + PKG_BUILD
13
13
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
14
14
  PKG_DESTINATION = ENV["RAILS_PKG_DESTINATION"] || "../#{PKG_NAME}"
15
15
 
@@ -25,8 +25,8 @@ PUBLIC_DIRS = %w( images javascripts stylesheets )
25
25
  TEST_DIRS = %w( fixtures unit functional mocks mocks/development mocks/test )
26
26
 
27
27
  LOG_FILES = %w( server.log development.log test.log production.log )
28
- HTML_FILES = %w( 404.html 500.html index.html favicon.ico javascripts/prototype.js )
29
- BIN_FILES = %w( generate destroy breakpointer console console_sandbox server update runner profiler benchmarker )
28
+ HTML_FILES = %w( 404.html 500.html index.html favicon.ico javascripts/prototype.js javascripts/effects.js javascripts/dragdrop.js javascripts/controls.js )
29
+ BIN_FILES = %w( generate destroy breakpointer console server update runner profiler benchmarker ) # listener tracker
30
30
 
31
31
  VENDOR_LIBS = %w( actionpack activerecord actionmailer activesupport actionwebservice railties )
32
32
 
@@ -59,6 +59,15 @@ task :clean do
59
59
  rm_rf PKG_DESTINATION
60
60
  end
61
61
 
62
+ # Get external spinoffs -------------------------------------------------------------------
63
+
64
+ desc "Updates railties to the latest version of the javascript spinoffs"
65
+ task :update_js do
66
+ for js in %w( prototype controls dragdrop effects )
67
+ rm "html/javascripts/#{js}.js"
68
+ cp "./../actionpack/lib/action_view/helpers/javascripts/#{js}.js", "html/javascripts"
69
+ end
70
+ end
62
71
 
63
72
  # Make directory structure ----------------------------------------------------------------
64
73
 
@@ -123,6 +132,9 @@ task :copy_dispatches do
123
132
 
124
133
  copy_with_rewritten_ruby_path("dispatches/dispatch.fcgi", "#{PKG_DESTINATION}/public/dispatch.fcgi")
125
134
  chmod 0755, "#{PKG_DESTINATION}/public/dispatch.fcgi"
135
+
136
+ # copy_with_rewritten_ruby_path("dispatches/gateway.cgi", "#{PKG_DESTINATION}/public/gateway.cgi")
137
+ # chmod 0755, "#{PKG_DESTINATION}/public/gateway.cgi"
126
138
  end
127
139
 
128
140
  task :copy_html_files do
@@ -239,11 +251,11 @@ spec = Gem::Specification.new do |s|
239
251
  EOF
240
252
 
241
253
  s.add_dependency('rake', '>= 0.5.3')
242
- s.add_dependency('activesupport', '= 1.0.4' + PKG_BUILD)
243
- s.add_dependency('activerecord', '= 1.10.1' + PKG_BUILD)
244
- s.add_dependency('actionpack', '= 1.8.1' + PKG_BUILD)
245
- s.add_dependency('actionmailer', '= 0.9.1' + PKG_BUILD)
246
- s.add_dependency('actionwebservice', '= 0.7.1' + PKG_BUILD)
254
+ s.add_dependency('activesupport', '= 1.1.0' + PKG_BUILD)
255
+ s.add_dependency('activerecord', '= 1.11.0' + PKG_BUILD)
256
+ s.add_dependency('actionpack', '= 1.9.0' + PKG_BUILD)
257
+ s.add_dependency('actionmailer', '= 1.0.0' + PKG_BUILD)
258
+ s.add_dependency('actionwebservice', '= 0.8.0' + PKG_BUILD)
247
259
 
248
260
  s.rdoc_options << '--exclude' << '.'
249
261
  s.has_rdoc = false
@@ -268,8 +280,8 @@ end
268
280
  # Publishing -------------------------------------------------------
269
281
  desc "Publish the API documentation"
270
282
  task :pgem => [:gem] do
271
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
272
- `ssh davidhh@wrath.rubyonrails.com './gemupdate.sh'`
283
+ Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
284
+ `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
273
285
  end
274
286
 
275
287
  desc "Publish the release files to RubyForge."
@@ -385,4 +397,4 @@ task :release => [:gem] do
385
397
  first_file = false
386
398
  end
387
399
  end
388
- end
400
+ end
@@ -2,15 +2,16 @@
2
2
  irb = RUBY_PLATFORM =~ /mswin32/ ? 'irb.bat' : 'irb'
3
3
 
4
4
  require 'optparse'
5
- options = {}
5
+ options = { :sandbox => false, :irb => irb }
6
6
  OptionParser.new do |opt|
7
7
  opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |options[:sandbox]| }
8
+ opt.on("--irb=[#{irb}]", 'Invoke a different irb.') { |options[:irb]| }
8
9
  opt.parse!(ARGV)
9
10
  end
10
11
 
11
- libs = " -r #{File.dirname(__FILE__)}/../config/environment"
12
- libs << " -r #{File.dirname(__FILE__)}/console_sandbox" if options[:sandbox]
13
- libs << " -r irb/completion"
12
+ libs = " -r irb/completion"
13
+ libs << " -r #{File.dirname(__FILE__)}/../config/environment"
14
+ libs << " -r console_sandbox" if options[:sandbox]
14
15
 
15
16
  ENV['RAILS_ENV'] = ARGV.first || 'development'
16
17
  if options[:sandbox]
@@ -19,4 +20,4 @@ if options[:sandbox]
19
20
  else
20
21
  puts "Loading #{ENV['RAILS_ENV']} environment."
21
22
  end
22
- exec "#{irb} #{libs}"
23
+ exec "#{options[:irb]} #{libs} --prompt-mode simple"
@@ -1,6 +0,0 @@
1
- ActiveRecord::Base.lock_mutex
2
- ActiveRecord::Base.connection.begin_db_transaction
3
- at_exit do
4
- ActiveRecord::Base.connection.rollback_db_transaction
5
- ActiveRecord::Base.unlock_mutex
6
- end
@@ -0,0 +1,86 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'stringio'
4
+ require 'fileutils'
5
+ require 'fcgi_handler'
6
+
7
+ def message(s)
8
+ $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
9
+ end
10
+
11
+ class RemoteCGI < CGI
12
+ attr_accessor :stdinput, :stdoutput, :env_table
13
+ def initialize(env_table, input = nil, output = nil)
14
+ self.env_table = env_table
15
+ self.stdinput = input || StringIO.new
16
+ self.stdoutput = output || StringIO.new
17
+ super()
18
+ end
19
+
20
+ def out(stream) # Ignore the requested output stream
21
+ super(stdoutput)
22
+ end
23
+ end
24
+
25
+ class Listener
26
+ include DRbUndumped
27
+
28
+ def initialize(timeout, socket_path)
29
+ @socket = File.expand_path(socket_path)
30
+ @mutex = Mutex.new
31
+ @active = false
32
+ @timeout = timeout
33
+
34
+ @handler = RailsFCGIHandler.new
35
+ @handler.extend DRbUndumped
36
+
37
+ message 'opening socket'
38
+ DRb.start_service("drbunix:#{@socket}", self)
39
+
40
+ message 'entering process loop'
41
+ @handler.process! self
42
+ end
43
+
44
+ def each_cgi(&cgi_block)
45
+ @cgi_block = cgi_block
46
+ message 'entering idle loop'
47
+ loop do
48
+ sleep @timeout rescue nil
49
+ die! unless @active
50
+ @active = false
51
+ end
52
+ end
53
+
54
+ def process(env, input)
55
+ message 'received request'
56
+ @mutex.synchronize do
57
+ @active = true
58
+
59
+ message 'creating input stream'
60
+ input_stream = StringIO.new(input)
61
+ message 'building CGI instance'
62
+ cgi = RemoteCGI.new(eval(env), input_stream)
63
+
64
+ message 'yielding to fcgi handler'
65
+ @cgi_block.call cgi
66
+ message 'yield finished -- sending output'
67
+
68
+ cgi.stdoutput.seek(0)
69
+ output = cgi.stdoutput.read
70
+
71
+ return output
72
+ end
73
+ end
74
+
75
+ def die!
76
+ message 'shutting down'
77
+ DRb.stop_service
78
+ FileUtils.rm_f @socket
79
+ Kernel.exit 0
80
+ end
81
+ end
82
+
83
+ socket_path = ARGV.shift
84
+ timeout = (ARGV.shift || 90).to_i
85
+
86
+ Listener.new(timeout, socket_path)
@@ -1,17 +1,34 @@
1
1
  #!/usr/local/bin/ruby
2
-
3
2
  if ARGV.empty?
4
- puts "Usage: profiler 'Person.expensive_method(10)' [times]"
5
- exit
3
+ $stderr.puts "Usage: profiler 'Person.expensive_method(10)' [times]"
4
+ exit(1)
6
5
  end
7
6
 
7
+ # Keep the expensive require out of the profile.
8
+ $stderr.puts 'Loading Rails...'
8
9
  require File.dirname(__FILE__) + '/../config/environment'
9
- require "profiler"
10
10
 
11
- # Don't include compilation in the profile
12
- eval(ARGV.first)
11
+ # Define a method to profile.
12
+ if ARGV[1] and ARGV[1].to_i > 1
13
+ eval "def profile_me() #{ARGV[1]}.times { #{ARGV[0]} } end"
14
+ else
15
+ eval "def profile_me() #{ARGV[0]} end"
16
+ end
13
17
 
14
- Profiler__::start_profile
15
- (ARGV[1] || 1).to_i.times { eval(ARGV.first) }
16
- Profiler__::stop_profile
17
- Profiler__::print_profile($stdout)
18
+ # Use the ruby-prof extension if available. Fall back to stdlib profiler.
19
+ begin
20
+ require 'prof'
21
+ $stderr.puts 'Using the ruby-prof extension.'
22
+ Prof.clock_mode = Prof::GETTIMEOFDAY
23
+ Prof.start
24
+ profile_me
25
+ results = Prof.stop
26
+ require 'rubyprof_ext'
27
+ Prof.print_profile(results, $stderr)
28
+ rescue LoadError
29
+ $stderr.puts 'Using the standard Ruby profiler.'
30
+ Profiler__.start_profile
31
+ profile_me
32
+ Profiler__.stop_profile
33
+ Profiler__.print_profile($stderr)
34
+ end
data/bin/rails CHANGED
@@ -1,6 +1,8 @@
1
1
  abort "Rails requires Ruby 1.8.2" if RUBY_VERSION < "1.8.2"
2
2
 
3
+ Signal.trap("INT") { puts; exit }
4
+
3
5
  require File.dirname(__FILE__) + '/../lib/rails_generator'
4
6
  require 'rails_generator/scripts/generate'
5
7
  Rails::Generator::Base.use_application_sources!
6
- Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
8
+ Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
data/bin/runner CHANGED
@@ -1,3 +1,27 @@
1
+ require 'optparse'
2
+
3
+ options = { :environment => "development" }
4
+
5
+ ARGV.options do |opts|
6
+ script_name = File.basename($0)
7
+ opts.banner = "Usage: runner 'puts Person.find(1).name' [options]"
8
+
9
+ opts.separator ""
10
+
11
+ opts.on("-e", "--environment=name", String,
12
+ "Specifies the environment for the runner to operate under (test/development/production).",
13
+ "Default: development") { |options[:environment]| }
14
+
15
+ opts.separator ""
16
+
17
+ opts.on("-h", "--help",
18
+ "Show this help message.") { puts opts; exit }
19
+
20
+ opts.parse!
21
+ end
22
+
23
+ ENV["RAILS_ENV"] = options[:environment]
24
+
1
25
  #!/usr/local/bin/ruby
2
26
 
3
27
  require File.dirname(__FILE__) + '/../config/environment'
data/bin/server CHANGED
@@ -45,4 +45,5 @@ require 'webrick_server'
45
45
  OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)
46
46
 
47
47
  puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
48
+ puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer
48
49
  DispatchServlet.dispatch(OPTIONS)
@@ -0,0 +1,69 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'drb'
4
+ require 'thread'
5
+
6
+ def message(s)
7
+ $stderr.puts "tracker: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
8
+ end
9
+
10
+ class Tracker
11
+ include DRbUndumped
12
+
13
+ def initialize(instances, socket_path)
14
+ @instances = instances
15
+ @socket = File.expand_path(socket_path)
16
+ @active = false
17
+
18
+ @listeners = []
19
+ @instances.times { @listeners << Mutex.new }
20
+
21
+ message "using #{@listeners.length} listeners"
22
+ message "opening socket at #{@socket}"
23
+
24
+ @service = DRb.start_service("drbunix://#{@socket}", self)
25
+ end
26
+
27
+ def with_listener
28
+ message "listener requested"
29
+
30
+ mutex = has_lock = index = nil
31
+ 3.times do
32
+ @listeners.each_with_index do |mutex, index|
33
+ has_lock = mutex.try_lock
34
+ break if has_lock
35
+ end
36
+ break if has_lock
37
+ sleep 0.05
38
+ end
39
+
40
+ if has_lock
41
+ message "obtained listener #{index}"
42
+ @active = true
43
+ begin yield index
44
+ ensure
45
+ mutex.unlock
46
+ message "released listener #{index}"
47
+ end
48
+ else
49
+ message "dropping request because no listeners are available!"
50
+ end
51
+ end
52
+
53
+ def background(check_interval = nil)
54
+ if check_interval
55
+ loop do
56
+ sleep check_interval
57
+ message "Idle for #{check_interval}, shutting down" unless @active
58
+ @active = false
59
+ Kernel.exit 0
60
+ end
61
+ else DRb.thread.join
62
+ end
63
+ end
64
+ end
65
+
66
+ socket_path = ARGV.shift
67
+ instances = ARGV.shift.to_i
68
+ t = Tracker.new(instances, socket_path)
69
+ t.background(ARGV.first ? ARGV.shift.to_i : 90)