mongrel_cow_cluster 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ v0.3.5 fix default timeout to match Mongrel default; respect "num_procs" for mongrel_cluster compatibility
2
+ v0.3.4 load configuration file before validation
3
+ v0.3.3 respect "address" in config for mongrel_cluster compatibility
4
+ v0.3.1 bind to a random port on 127.0.0.1 to preload Rails
5
+ v0.3.0 rolling_interval option added to delay between member restarts
data/LICENSE ADDED
@@ -0,0 +1,56 @@
1
+ cow_cluster is copyrighted free software by Eric Wong <normalperson@yhbt.net>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ version 2 (see the file GPL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -0,0 +1,7 @@
1
+ CHANGELOG
2
+ README
3
+ Manifest
4
+ LICENSE
5
+ lib/mongrel_cow_cluster/init.rb
6
+ resources/defaults.yaml
7
+ tools/rakehelp.rb
data/README ADDED
@@ -0,0 +1,133 @@
1
+ MongrelCowCluster
2
+ by Eric Wong <normalperson@yhbt.net>
3
+ FIX (http://rubyforge.org/projects/mongrel-cow/)
4
+
5
+ == DESCRIPTION:
6
+
7
+ A faster, Rails-only replacement for mongrel_cluster
8
+
9
+ Uses copy-on-write fork() to drastically reduce startup times when
10
+ starting mongrel server. This means all of the Rails and environment
11
+ code is read and loaded _once_ and forked N times where N is the number
12
+ of ports one wishes to bind to.
13
+
14
+ It is very similar to mongrel_cluster in use and can use config files
15
+ generated for mongrel_cluster. This still creates pid and log files
16
+ that are similar to those used by mongrel_cluster (mongrel.<port>.log
17
+ and mongrel.<port>.pid).
18
+
19
+ All children are independent of each other and the death of one will
20
+ not influence another. The parent process dies as soon as the final
21
+ child is spawned.
22
+
23
+ Unlike traditional non-Ruby applications that use copy-on-write fork()
24
+ to save memory, do NOT expect any significant memory savings even though
25
+ this uses copy-on-write(), since the Ruby GC will trigger writes on
26
+ whatever pages it marks. The main performance benefit of this is that
27
+ the application code can be parsed once and reused.
28
+
29
+ If you connect to any other databases or services at Rails startup, you
30
+ will need to re-init them manually. The default ActiveRecord::Base
31
+ connection provided by Rails is disconnected after Rails is loaded
32
+ and restarted/reconnected in each child process.
33
+
34
+
35
+ == FEATURES/PROBLEMS:
36
+
37
+ Rolling restarts:
38
+
39
+ Although machines are all issued cow_cluster restart commands at
40
+ the same time (by Capistrano), each individual mongrel process
41
+ will be restarted independently of the others. This means that
42
+ (assuming this works correctly :), only ONE mongrel process
43
+ per machine will be down at any given time. This makes life
44
+ a lot easier for the Apache proxies (which will failover to
45
+ the next available port) and *should* be completely transparent
46
+ to the end user.
47
+
48
+ We now also check for successful startup of each individual port
49
+ by issuing an HTTP GET on "/" and report back to the person
50
+ running cow_cluster if that server has been successfully
51
+ started.
52
+
53
+ Daemonization is handled internally by cow_cluster since
54
+ Daemons::Daemonize (used by Mongrel) does too many things behind
55
+ our back wrt closing AR:B connections and redirecting log
56
+ files of the managing process.
57
+
58
+ == SYNOPSIS:
59
+
60
+ Start:
61
+ mongrel_rails cow_cluster::start -C config/mongrel_cluster.yml
62
+ Stop:
63
+ mongrel_rails cow_cluster::stop -C config/mongrel_cluster.yml
64
+ Restart:
65
+ mongrel_rails cow_cluster::restart -C config/mongrel_cluster.yml
66
+
67
+ == REQUIREMENTS:
68
+
69
+ gem_plugin >= 0.2.2
70
+ mongrel >= 1.0.1
71
+
72
+ == INSTALL:
73
+
74
+ sudo gem install mongrel_cow_cluster
75
+
76
+ == LICENSE:
77
+
78
+ cow_cluster is copyrighted free software by Eric Wong <normalperson@yhbt.net>.
79
+ You can redistribute it and/or modify it under either the terms of the GPL
80
+ version 2 (see the file GPL), or the conditions below:
81
+
82
+ 1. You may make and give away verbatim copies of the source form of the
83
+ software without restriction, provided that you duplicate all of the
84
+ original copyright notices and associated disclaimers.
85
+
86
+ 2. You may modify your copy of the software in any way, provided that
87
+ you do at least ONE of the following:
88
+
89
+ a) place your modifications in the Public Domain or otherwise
90
+ make them Freely Available, such as by posting said
91
+ modifications to Usenet or an equivalent medium, or by allowing
92
+ the author to include your modifications in the software.
93
+
94
+ b) use the modified software only within your corporation or
95
+ organization.
96
+
97
+ c) give non-standard binaries non-standard names, with
98
+ instructions on where to get the original software distribution.
99
+
100
+ d) make other distribution arrangements with the author.
101
+
102
+ 3. You may distribute the software in object code or binary form,
103
+ provided that you do at least ONE of the following:
104
+
105
+ a) distribute the binaries and library files of the software,
106
+ together with instructions (in the manual page or equivalent)
107
+ on where to get the original distribution.
108
+
109
+ b) accompany the distribution with the machine-readable source of
110
+ the software.
111
+
112
+ c) give non-standard binaries non-standard names, with
113
+ instructions on where to get the original software distribution.
114
+
115
+ d) make other distribution arrangements with the author.
116
+
117
+ 4. You may modify and include the part of the software into any other
118
+ software (possibly commercial). But some files in the distribution
119
+ are not written by the author, so that they are not under these terms.
120
+
121
+ For the list of those files and their copying conditions, see the
122
+ file LEGAL.
123
+
124
+ 5. The scripts and library files supplied as input to or produced as
125
+ output from the software do not automatically fall under the
126
+ copyright of the software, but belong to whomever generated them,
127
+ and may be sold commercially, and may be aggregated with this
128
+ software.
129
+
130
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
131
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
132
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
133
+ PURPOSE.
@@ -0,0 +1,437 @@
1
+ # Copyright (c) 2007 Eric Wong
2
+ # Based on code from Mongrel, Copyright (c) 2005 Zed A. Shaw
3
+ #
4
+ # You can redistribute it and/or modify it under the same terms as Ruby.
5
+ #
6
+ # Additional work donated by contributors.
7
+ # See http://mongrel.rubyforge.org/attributions.html for more information.
8
+
9
+ require 'gem_plugin'
10
+ require 'mongrel'
11
+ require 'net/http'
12
+
13
+ module Cow_Cluster
14
+ module Base
15
+
16
+ def read_options(settings)
17
+ if @config_file
18
+ settings.merge!(config_settings = YAML.load_file(@config_file))
19
+ # symbolize keys, mongrel_cluster uses string keys :(
20
+ keys = settings.keys.collect { |k| k.kind_of?(Symbol) ? nil : k }
21
+ keys.compact.each { |k| settings[k.to_sym] = settings.delete(k) }
22
+ STDERR.puts "** Loading settings from #{@config_file} " +
23
+ "(they override command line)."
24
+ if settings[:address] && ! config_settings[:host]
25
+ settings[:host] = settings[:address]
26
+ end
27
+ settings.each { |k,v| instance_variable_set("@#{k.to_s}", v) }
28
+ end
29
+
30
+ @file = { :pid => {}, :log => {} }
31
+ @file.keys.each { |f|
32
+ x = "#{f.to_s}_file".to_sym
33
+ next unless settings[x]
34
+ @file[f][:ext] = File.extname(settings[x])
35
+ @file[f][:base] = File.basename(settings[x], @file[f][:ext])
36
+ @file[f][:dir] = File.dirname(settings[x])
37
+ }
38
+ end
39
+
40
+ def each_port(settings, &block)
41
+ if settings[:only]
42
+ yield settings[:only]
43
+ else
44
+ max_port = settings[:port] + settings[:servers] - 1
45
+ (settings[:port]..max_port).each { |port|
46
+ yield port
47
+ }
48
+ end
49
+ end
50
+
51
+ def port_pid_file(port)
52
+ base = "#{@file[:pid][:base]}.#{port}#{@file[:pid][:ext]}"
53
+ File.join(@file[:pid][:dir], base)
54
+ end
55
+
56
+ def port_log_file(port)
57
+ base = "#{@file[:log][:base]}.#{port}#{@file[:log][:ext]}"
58
+ File.join(@file[:log][:dir], base)
59
+ end
60
+
61
+ def stop_options
62
+ [
63
+ ['-c', '--chdir PATH',
64
+ "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
65
+ ['-C', '--config PATH', "Use a config file", :@config_file, nil],
66
+ ['-f', '--force', "Force the shutdown (kill -9).", :@force, false],
67
+ ['-o', '--only INT', 'Limit operation to only one port', :@only, nil ],
68
+ ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown",
69
+ :@wait, "10"],
70
+ ['-p', '--port INT', "First port to bind to", :@port, 3000],
71
+ ['-s', '--servers INT', "Number of servers to start", :@servers, 2],
72
+ ['-P', '--pid FILE', "Where to write the PID", :@pid_file,
73
+ "log/mongrel.pid"],
74
+ ]
75
+ end
76
+
77
+ def validate_stop_options
78
+ if @config_file
79
+ valid_exists? @config_file, "Config file not there: #@config_file"
80
+ load_settings
81
+ end
82
+ @cwd = File.expand_path(@cwd)
83
+ valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
84
+ Dir.chdir @cwd
85
+
86
+ @valid
87
+ end
88
+
89
+ def start_options(restart = false)
90
+ ret = [
91
+ ["-e", "--environment ENV", "Rails environment to run as",
92
+ :@environment, ENV['RAILS_ENV'] || "development"],
93
+ ['-p', '--port INT', "First port to bind to", :@port, 3000],
94
+ ['-s', '--servers INT', "Number of servers to start", :@servers, 2],
95
+ ['-a', '--address ADDR', "Address to bind to", :@address, "0.0.0.0"],
96
+ ['-l', '--log FILE', "Where to write log messages", :@log_file,
97
+ "log/mongrel.log"],
98
+ ['-P', '--pid FILE', "Where to write the PID", :@pid_file,
99
+ "log/mongrel.pid"],
100
+ ['-n', '--num-procs INT',
101
+ "Number of processors active before clients denied",
102
+ :@num_procs, 1024],
103
+ ['-t', '--timeout TIME',
104
+ "Timeout all requests after seconds time", :@timeout, 60],
105
+ ['-m', '--mime PATH', "A YAML file that lists additional MIME types",
106
+ :@mime_map, nil],
107
+ ['-c', '--chdir PATH',
108
+ "Change to dir before starting (will be expanded)", :@cwd, Dir.pwd],
109
+ ['-r', '--root PATH', "Set the document root (default 'public')",
110
+ :@docroot, "public"],
111
+ ['-B', '--debug', "Enable debugging mode", :@debug, false],
112
+ ['-C', '--config PATH', "Use a config file", :@config_file, nil],
113
+ ['-S', '--script PATH',
114
+ "Load the given file as an extra config script",
115
+ :@config_script, nil],
116
+ ['-o', '--only INT', 'Limit operation to only one port', :@only, nil ],
117
+ ['', '--user USER', "User to run as", :@user, nil],
118
+ ['', '--group GROUP', "Group to run as", :@group, nil],
119
+ ['', '--prefix PATH', "URL prefix for Rails app", :@prefix, nil]
120
+ ]
121
+ if restart
122
+ seen = {}
123
+ ret.each { |o| seen[o[1]] = true }
124
+ stop_options.each { |o|
125
+ ret << o unless seen[o[1]]
126
+ }
127
+ ret << [ '-i', '--rolling-interval SECONDS',
128
+ "Seconds to delay between each child restart",
129
+ :@rolling_interval, nil]
130
+ end
131
+ ret
132
+ end
133
+
134
+ def validate_start_options
135
+ if @config_file
136
+ valid_exists? @config_file, "Config file not there: #@config_file"
137
+ load_settings
138
+ end
139
+ @cwd = File.expand_path(@cwd)
140
+ valid_dir? @cwd, "Invalid path to change to during daemon mode: #@cwd"
141
+
142
+ # Change there to start, then we'll have to come back after daemonize
143
+ Dir.chdir(@cwd)
144
+
145
+ valid?(@prefix[0].chr == "/" && @prefix[-1].chr != "/",
146
+ "Prefix must begin with / and not end in /") if @prefix
147
+ valid_dir? File.dirname(@log_file),
148
+ "Path to log file not valid: #@log_file"
149
+ valid_dir? File.dirname(@pid_file),
150
+ "Path to pid file not valid: #@pid_file"
151
+ valid_dir? @docroot, "Path to docroot not valid: #@docroot"
152
+ valid_exists? @mime_map, "MIME mapping file does not exist: #@mime_map" \
153
+ if @mime_map
154
+ valid_user? @user if @user
155
+ valid_group? @group if @group
156
+
157
+ return @valid
158
+ end
159
+
160
+ def stop_child(settings, port, force = @force)
161
+ pid_file = port_pid_file(port)
162
+
163
+ if File.exist?(pid_file)
164
+ signal = force ? 'KILL' : 'TERM'
165
+ pid = File.open(pid_file).read.to_i
166
+ STDERR.print "Sending #{signal} to Mongrel at PID #{pid}..."
167
+ begin
168
+ Process.kill(signal, pid)
169
+ rescue Errno::ESRCH
170
+ STDERR.puts 'Process does not exist. Not running.'
171
+ File.unlink(pid_file)
172
+ end
173
+ if force
174
+ File.unlink(pid_file) rescue nil
175
+ else
176
+ @wait.to_i.times { |nr| sleep(1) if File.exist?(pid_file) }
177
+ end
178
+ STDERR.puts 'Done.'
179
+ else
180
+ STDERR.puts "#{pid_file} not found, skipping."
181
+ end
182
+ end
183
+
184
+ def load_settings
185
+ # Config file settings will override command line settings
186
+ settings = { :host => @address, :port => @port, :cwd => @cwd,
187
+ :log_file => @log_file, :pid_file => @pid_file,
188
+ :environment => @environment,
189
+ :docroot => @docroot, :mime_map => @mime_map,
190
+ :debug => @debug, :includes => ["mongrel"],
191
+ :config_script => @config_script,
192
+ :num_processors => @num_procs, :timeout => @timeout,
193
+ :servers => @servers,
194
+ :user => @user, :group => @group, :prefix => @prefix,
195
+ :only => @only, :rolling_interval => @rolling_interval,
196
+ :config_file => @config_file
197
+ }
198
+ read_options(settings)
199
+ settings
200
+ end
201
+
202
+ def restart_run(restart = false)
203
+ settings = load_settings
204
+ settings.merge(:force => @force, :wait => @wait) if restart
205
+ config = rails_preload(settings)
206
+ ObjectSpace.each_object(TCPServer) { |x| x.close rescue nil }
207
+
208
+ close_rails_connections
209
+
210
+ pid = fork {
211
+ File.umask 0000
212
+ Process.setsid
213
+ trap 'HUP', 'IGNORE'
214
+ Dir.chdir(@cwd)
215
+ ri = nil
216
+ each_port(settings) { |port|
217
+ if restart && settings[:rolling_interval]
218
+ if ri
219
+ STDERR.puts "Delaying next restart by #{ri} seconds " +
220
+ "(rolling-interval)"
221
+ sleep(ri)
222
+ else
223
+ ri = settings[:rolling_interval].to_f
224
+ end
225
+ end
226
+
227
+ GC.start
228
+ if restart
229
+ stop_child(settings, port)
230
+ GC.start
231
+ end
232
+
233
+ spawn_child(settings, port)
234
+ }
235
+ }
236
+ Process.waitpid(pid)
237
+ exit 0
238
+ end # restart_run
239
+
240
+ def write_child_pid(settings)
241
+ pid_file = settings[:pid_file]
242
+ if File.exist?(pid_file)
243
+ STDERR.puts "!!! PID file #{pid_file} already exists." +
244
+ " Mongrel could be running already. " +
245
+ "Check your #{settings[:log_file]} for errors."
246
+ STDERR.puts "!!! Exiting with error. " +
247
+ "You must stop mongrel and clear the .pid " +
248
+ "before I'll attempt a start."
249
+ exit 1
250
+ end
251
+
252
+ File.open(pid_file, 'w') { |fp| fp.puts $$.to_s }
253
+ end
254
+
255
+ def reopen_child_log(settings)
256
+ STDIN.reopen '/dev/null' rescue nil
257
+ STDOUT.reopen(settings[:log_file], 'a')
258
+ STDOUT.sync = true
259
+ STDERR.reopen(settings[:log_file], 'a')
260
+ STDERR.sync = true
261
+ end
262
+
263
+ def get_unbound_port
264
+ tmp_port = tmp_socket = nil
265
+ while ! tmp_socket do
266
+ begin
267
+ tmp_port = rand(32768) + 32768
268
+ tmp_socket = TCPServer.new('127.0.0.1', tmp_port)
269
+ rescue Errno::EADDRINUSE
270
+ STDERR.puts "Warning: failed temporarily bind to random port: " +
271
+ "#{tmp_port}, trying another..."
272
+ retry
273
+ end
274
+ end
275
+ tmp_socket.close
276
+ tmp_port
277
+ end
278
+
279
+ def rails_preload(settings)
280
+ GC.start
281
+
282
+ # start a random, temporary alternate port
283
+ settings = settings.dup
284
+ settings[:host] = '127.0.0.1'
285
+ settings[:port] = get_unbound_port
286
+ config = Mongrel::Rails::RailsConfigurator.new(settings) do
287
+ mime = {}
288
+ if defaults[:mime_map]
289
+ log "Loading additional MIME types from #{defaults[:mime_map]}"
290
+ mime = load_mime_map(defaults[:mime_map], mime)
291
+ end
292
+
293
+ listener do
294
+ uri defaults[:prefix] || "/",
295
+ :handler => rails(:mime => mime, :prefix => defaults[:prefix])
296
+ if defaults[:config_script]
297
+ log "Loading #{defaults[:config_script]} external config script"
298
+ run_config(defaults[:config_script])
299
+ end
300
+ log "Loading any Rails specific GemPlugins"
301
+ load_plugins
302
+ log "Rails loaded."
303
+ end
304
+ end # RailsConfigurator.new
305
+ config
306
+ end
307
+
308
+ def close_rails_connections
309
+ ActiveRecord::Base.connection.disconnect!
310
+ CACHE.reset if defined?(CACHE) && CACHE.respond_to?(:reset)
311
+ end
312
+
313
+ def open_rails_connections
314
+ ActiveRecord::Base.establish_connection
315
+ end
316
+
317
+ def wait_for_child_ready(address, port)
318
+ sleep 1
319
+ tries = 10
320
+ begin
321
+ http = Net::HTTP.new(address, port)
322
+ http.start
323
+ ret = http.get('/')
324
+ STDERR.puts "http://#{address}:#{port} ready: #{ret}"
325
+ rescue Errno::ECONNREFUSED => err
326
+ if (tries -= 1) > 0
327
+ STDERR.puts "Waiting for http://#{address}:#{port} to respond, " +
328
+ "#{tries} tries left"
329
+ sleep 1
330
+ retry
331
+ else
332
+ throw err
333
+ end
334
+ end
335
+ end
336
+
337
+ def spawn_child(settings, port)
338
+ fork {
339
+ GC.start
340
+ settings[:port] = port
341
+ settings[:pid_file] = port_pid_file(port)
342
+ settings[:log_file] = port_log_file(port)
343
+ write_child_pid(settings)
344
+ reopen_child_log(settings)
345
+
346
+ $0 << " -p #{port}"
347
+ open_rails_connections
348
+ config = Mongrel::Rails::RailsConfigurator.new(settings) do
349
+ if defaults[:debug]
350
+ log "Installing debugging prefixed filters. " +
351
+ "Look in log/mongrel_debug for the files."
352
+ debug "/"
353
+ end
354
+
355
+ listener do
356
+ uri defaults[:prefix] || "/", :handler => rails
357
+ if defaults[:config_script]
358
+ log "Loading #{defaults[:config_script]} external config script"
359
+ run_config(defaults[:config_script])
360
+ end
361
+ setup_rails_signals
362
+ end # listener
363
+
364
+ end # config
365
+ config.log "Mongrel available at #{settings[:host]}:#{port}"
366
+ config.run
367
+ GC.start
368
+ config.join
369
+ exit 0
370
+ } # fork
371
+ wait_for_child_ready(settings[:host], port)
372
+ rescue Object => err
373
+ STDERR.puts "Failed to spawn child on port #{port}: #{err.inspect}"
374
+ end # spawn_child
375
+ end
376
+
377
+
378
+ class Start < GemPlugin::Plugin "/commands"
379
+ include Mongrel::Command::Base
380
+ include Base
381
+
382
+ def configure
383
+ options start_options
384
+ end
385
+
386
+ def validate
387
+ validate_start_options
388
+ end
389
+
390
+ def run
391
+ restart_run(false)
392
+ end
393
+ end
394
+
395
+
396
+ class Stop < GemPlugin::Plugin "/commands"
397
+ include Mongrel::Command::Base
398
+ include Base
399
+
400
+ def configure
401
+ options stop_options
402
+ end
403
+
404
+ def validate
405
+ validate_stop_options
406
+ end
407
+
408
+ def run
409
+ settings = { :cwd => @cwd, :only => @only, :wait => @wait,
410
+ :port => @port, :servers => @servers,
411
+ :pid_file => @pid_file }
412
+ read_options(settings)
413
+
414
+ each_port(settings) { |port| stop_child(settings, port) }
415
+ end
416
+ end
417
+
418
+
419
+ class Restart < GemPlugin::Plugin "/commands"
420
+ include Mongrel::Command::Base
421
+ include Base
422
+
423
+ def configure
424
+ options start_options(true)
425
+ end
426
+
427
+ def validate
428
+ validate_stop_options && validate_start_options
429
+ end
430
+
431
+ def run
432
+ restart_run(true)
433
+ end
434
+ end
435
+
436
+ end
437
+
@@ -0,0 +1,47 @@
1
+
2
+ # Gem::Specification for Mongrel_cow_cluster-0.3.5
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{mongrel_cow_cluster}
7
+ s.version = "0.3.5"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Eric Wong"]
13
+ s.date = %q{2008-02-24}
14
+ s.description = %q{A Mongrel plugin that uses copy-on-write to lower resource impact and handle rolling restarts of several Mongrel processes.}
15
+ s.email = %q{}
16
+ s.files = ["CHANGELOG", "README", "Manifest", "LICENSE", "lib/mongrel_cow_cluster/init.rb", "resources/defaults.yaml", "tools/rakehelp.rb", "mongrel_cow_cluster.gemspec"]
17
+ s.has_rdoc = true
18
+ s.homepage = %q{http://mongrel-cow.rubyforge.org}
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{mongrel-cow}
21
+ s.rubygems_version = %q{0.9.4.7}
22
+ s.summary = %q{A Mongrel plugin that uses copy-on-write to lower resource impact and handle rolling restarts of several Mongrel processes.}
23
+
24
+ s.add_dependency(%q<mongrel>, [">= 0", "= 1.0.1"])
25
+ end
26
+
27
+
28
+ # # Original Rakefile source (requires the Echoe gem):
29
+ #
30
+ # require 'echoe'
31
+ # echoe = Echoe.new('mongrel_cow_cluster') do |p|
32
+ # p.author = 'Eric Wong'
33
+ # p.summary = 'A Mongrel plugin that uses copy-on-write to lower ' \
34
+ # 'resource impact and handle rolling restarts of ' \
35
+ # 'several Mongrel processes.'
36
+ # p.url = 'http://mongrel-cow.rubyforge.org'
37
+ # p.rubyforge_name = 'mongrel-cow'
38
+ # p.dependencies = [ 'mongrel >= 1.0.1' ]
39
+ # end
40
+ #
41
+ # task :eric_release => [:clean, :package] do
42
+ # sh %{git log > pkg/#{echoe.name}-changelog}
43
+ # FileUtils.rmtree "pkg/#{echoe.name}-#{echoe.version}"
44
+ # sh %{git tag -s -u normalperson@yhbt.net v#{echoe.version}}
45
+ # sh %{git push bogomips}
46
+ # sh %{rsync -av pkg/ bogomips.org:/srv/bogomips/ruby/}
47
+ # end
@@ -0,0 +1,2 @@
1
+ ---
2
+ :debug: false
@@ -0,0 +1,123 @@
1
+
2
+ def make(makedir)
3
+ Dir.chdir(makedir) do
4
+ sh(PLATFORM =~ /win32/ ? 'nmake' : 'make')
5
+ end
6
+ end
7
+
8
+
9
+ def extconf(dir)
10
+ Dir.chdir(dir) do ruby "extconf.rb" end
11
+ end
12
+
13
+
14
+ def setup_tests
15
+ Rake::TestTask.new do |t|
16
+ t.libs << "test"
17
+ t.test_files = FileList['test/test*.rb']
18
+ t.verbose = true
19
+ end
20
+ end
21
+
22
+
23
+ def setup_clean otherfiles
24
+ files = ['build/*', '**/*.o', '**/*.so', '**/*.a', 'lib/*-*', '**/*.log'] + otherfiles
25
+ CLEAN.include(files)
26
+ end
27
+
28
+
29
+ def setup_rdoc files
30
+ Rake::RDocTask.new do |rdoc|
31
+ rdoc.rdoc_dir = 'doc/rdoc'
32
+ rdoc.options << '--line-numbers'
33
+ rdoc.rdoc_files.add(files)
34
+ end
35
+ end
36
+
37
+
38
+ def setup_extension(dir, extension)
39
+ ext = "ext/#{dir}"
40
+ ext_so = "#{ext}/#{extension}.#{Config::CONFIG['DLEXT']}"
41
+ ext_files = FileList[
42
+ "#{ext}/*.c",
43
+ "#{ext}/*.h",
44
+ "#{ext}/extconf.rb",
45
+ "#{ext}/Makefile",
46
+ "lib"
47
+ ]
48
+
49
+ task "lib" do
50
+ directory "lib"
51
+ end
52
+
53
+ desc "Builds just the #{extension} extension"
54
+ task extension.to_sym => ["#{ext}/Makefile", ext_so ]
55
+
56
+ file "#{ext}/Makefile" => ["#{ext}/extconf.rb"] do
57
+ extconf "#{ext}"
58
+ end
59
+
60
+ file ext_so => ext_files do
61
+ make "#{ext}"
62
+ cp ext_so, "lib"
63
+ end
64
+ end
65
+
66
+
67
+ def base_gem_spec(pkg_name, pkg_version)
68
+ pkg_version = pkg_version
69
+ pkg_name = pkg_name
70
+ pkg_file_name = "#{pkg_name}-#{pkg_version}"
71
+ Gem::Specification.new do |s|
72
+ s.name = pkg_name
73
+ s.version = pkg_version
74
+ s.platform = Gem::Platform::RUBY
75
+ s.has_rdoc = true
76
+ s.extra_rdoc_files = [ "README.txt" ]
77
+
78
+ s.files = %w(COPYING README.txt Rakefile) +
79
+ Dir.glob("{bin,doc/rdoc,test,lib}/**/*") +
80
+ Dir.glob("ext/**/*.{h,c,rb}") +
81
+ Dir.glob("examples/**/*.rb") +
82
+ Dir.glob("tools/*.rb")
83
+
84
+ s.require_path = "lib"
85
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
86
+ s.bindir = "bin"
87
+ end
88
+ end
89
+
90
+ def setup_gem(pkg_name, pkg_version)
91
+ spec = base_gem_spec(pkg_name, pkg_version)
92
+ yield spec if block_given?
93
+
94
+ Rake::GemPackageTask.new(spec) do |p|
95
+ p.gem_spec = spec
96
+ # win32 chokes on this
97
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
98
+ end
99
+ end
100
+
101
+ def setup_win32_gem(pkg_name, pkg_version)
102
+ spec = base_gem_spec(pkg_name, pkg_version)
103
+ yield spec if block_given?
104
+
105
+ Gem::Builder.new(spec).build
106
+ end
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4.7
3
+ specification_version: 2
4
+ name: mongrel_cow_cluster
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.3.5
7
+ date: 2008-02-24 00:00:00 -08:00
8
+ summary: A Mongrel plugin that uses copy-on-write to lower resource impact and handle rolling restarts of several Mongrel processes.
9
+ require_paths:
10
+ - lib
11
+ email: ""
12
+ homepage: http://mongrel-cow.rubyforge.org
13
+ rubyforge_project: mongrel-cow
14
+ description: A Mongrel plugin that uses copy-on-write to lower resource impact and handle rolling restarts of several Mongrel processes.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ required_rubygems_version: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: "0"
30
+ version:
31
+ platform: ruby
32
+ signing_key:
33
+ cert_chain: []
34
+
35
+ post_install_message:
36
+ authors:
37
+ - Eric Wong
38
+ files:
39
+ - CHANGELOG
40
+ - README
41
+ - Manifest
42
+ - LICENSE
43
+ - lib/mongrel_cow_cluster/init.rb
44
+ - resources/defaults.yaml
45
+ - tools/rakehelp.rb
46
+ - mongrel_cow_cluster.gemspec
47
+ test_files: []
48
+
49
+ rdoc_options: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ requirements: []
58
+
59
+ dependencies:
60
+ - !ruby/object:Gem::Dependency
61
+ name: mongrel
62
+ version_requirement:
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ - - "="
69
+ - !ruby/object:Gem::Version
70
+ version: 1.0.1
71
+ version: