pastry 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/pastry +7 -0
- data/lib/pastry.rb +42 -18
- metadata +2 -2
data/bin/pastry
CHANGED
@@ -16,10 +16,17 @@ parser = OptionParser.new do |opts|
|
|
16
16
|
opts.on('-d', '--[no-]daemon', 'daemonize') {|value| options[:daemonize] = value }
|
17
17
|
opts.on('-l', '--logfile file', 'logfile') {|value| options[:logfile] = value }
|
18
18
|
opts.on('-P', '--pidfile file', 'pidfile') {|value| options[:pidfile] = value }
|
19
|
+
opts.on('-c', '--connections num', 'max connections') {|value| options[:maxconn] = value }
|
20
|
+
opts.on('-t', '--timeout secs', 'read timeout') {|value| options[:timeout] = value }
|
21
|
+
opts.on('-A', '--application name', 'app name') {|value| options[:name] = value }
|
19
22
|
end
|
20
23
|
|
21
24
|
parser.parse!
|
22
25
|
|
26
|
+
%w(workers port maxconn timeout).map(&:to_sym).each do |name|
|
27
|
+
options[name] = options[name].to_i if options.key?(name)
|
28
|
+
end
|
29
|
+
|
23
30
|
app = Rack::Builder.parse_file(options.delete(:rackup) || 'config.ru').first
|
24
31
|
size = options.delete(:workers) || 2
|
25
32
|
env = options.delete(:env) || 'development'
|
data/lib/pastry.rb
CHANGED
@@ -10,18 +10,29 @@ class Pastry
|
|
10
10
|
@pool = pool
|
11
11
|
@app = app
|
12
12
|
@host = options.fetch :host, '127.0.0.1'
|
13
|
-
@port = options.fetch :port, 3000
|
14
13
|
@unix = options.fetch :socket, nil
|
15
|
-
@queue = options.fetch :queue, 1024
|
16
14
|
@logfile = options.fetch :logfile, nil
|
17
15
|
@daemon = options.fetch :daemonize, false
|
18
16
|
@pidfile = options.fetch :pidfile, '/tmp/pastry.pid'
|
19
|
-
|
17
|
+
@name = options.fetch :name, nil
|
18
|
+
|
19
|
+
@port = options.fetch(:port, 3000).to_i
|
20
|
+
@queue = options.fetch(:queue, 1024).to_i
|
21
|
+
@maxconn = options.fetch(:maxconn, 1024).to_i
|
22
|
+
@timeout = options.fetch(:timeout, 30).to_i
|
20
23
|
end
|
21
24
|
|
22
25
|
def start
|
23
26
|
ensure_not_running!
|
24
27
|
Process.daemon if daemon
|
28
|
+
|
29
|
+
if daemon || logfile
|
30
|
+
STDOUT.reopen(logfile || '/tmp/pastry.log', 'a')
|
31
|
+
STDERR.reopen(logfile || '/tmp/pastry.log', 'a')
|
32
|
+
STDOUT.sync = true
|
33
|
+
STDERR.sync = true
|
34
|
+
end
|
35
|
+
|
25
36
|
start!
|
26
37
|
end
|
27
38
|
|
@@ -37,8 +48,12 @@ class Pastry
|
|
37
48
|
File.open(pidfile, 'w') {|fh| fh.write(Process.pid)}
|
38
49
|
end
|
39
50
|
|
51
|
+
def name
|
52
|
+
'%s master' % (@name || 'pastry')
|
53
|
+
end
|
54
|
+
|
40
55
|
def motd
|
41
|
-
"starting #{
|
56
|
+
"starting #{name} with #{pool} minions listening on #{unix ? 'socket %s ' % unix : 'port %d' % port}"
|
42
57
|
end
|
43
58
|
|
44
59
|
def start!
|
@@ -51,39 +66,45 @@ class Pastry
|
|
51
66
|
server.listen(@queue)
|
52
67
|
server.extend(PastryServer)
|
53
68
|
|
54
|
-
@running = true
|
55
69
|
server.app = @app
|
56
|
-
logger = Logger.new(logfile || daemon ? '/tmp/pastry.log' : $stdout, 0)
|
57
|
-
|
70
|
+
logger = Logger.new(logfile || (daemon ? '/tmp/pastry.log' : $stdout), 0)
|
71
|
+
options = {timeout: @timeout, maximum_connections: @maxconn}
|
58
72
|
|
59
73
|
logger.info motd
|
74
|
+
|
75
|
+
$0 = name if @name
|
76
|
+
@running = true
|
77
|
+
pids = pool.times.map {|n| run(server, options, n) }
|
78
|
+
|
60
79
|
Signal.trap('CHLD') do
|
61
|
-
|
80
|
+
if @running
|
62
81
|
died = pids.reject {|pid| Process.kill(0, pid) rescue nil}
|
63
|
-
pids -= died
|
64
82
|
died.each do |pid|
|
65
83
|
logger.info "process #{pid} died, starting a new one"
|
66
|
-
pids
|
84
|
+
idx = pids.index(pid)
|
85
|
+
pids[idx] = run(server, options, idx)
|
67
86
|
end
|
68
87
|
end
|
69
88
|
end
|
70
89
|
|
71
|
-
at_exit { FileUtils.rm_f(pidfile) }
|
72
|
-
|
73
90
|
%w(INT TERM HUP).each do |signal|
|
74
91
|
Signal.trap(signal) do
|
75
92
|
@running = false
|
76
93
|
logger.info "caught #{signal}, closing time for the bakery -- no more pastries!"
|
77
|
-
pids.each {|pid| Process.kill(signal, pid) }
|
94
|
+
pids.each {|pid| Process.kill(signal, pid) rescue nil}
|
78
95
|
exit
|
79
96
|
end
|
80
97
|
end
|
81
98
|
|
99
|
+
at_exit { FileUtils.rm_f(pidfile); FileUtils.rm_f(unix.to_s) }
|
82
100
|
Process.waitall rescue nil
|
83
101
|
end
|
84
102
|
|
85
|
-
def run server
|
86
|
-
fork
|
103
|
+
def run server, options, worker
|
104
|
+
fork do
|
105
|
+
$0 = "#{@name ? "%s worker" % @name : "pastry chef"} #{worker} (started: #{Time.now})"
|
106
|
+
EM.run { Backend.new(options).start(server) }
|
107
|
+
end
|
87
108
|
end
|
88
109
|
|
89
110
|
module PastryServer
|
@@ -91,6 +112,11 @@ class Pastry
|
|
91
112
|
end
|
92
113
|
|
93
114
|
class Backend < Thin::Backends::Base
|
115
|
+
def initialize options = {}
|
116
|
+
super()
|
117
|
+
options.each {|key, value| send("#{key}=", value)}
|
118
|
+
end
|
119
|
+
|
94
120
|
def start server
|
95
121
|
@stopping = false
|
96
122
|
@running = true
|
@@ -103,9 +129,7 @@ class Pastry
|
|
103
129
|
end
|
104
130
|
|
105
131
|
def trap_signals!
|
106
|
-
%w(INT TERM HUP CHLD).each
|
107
|
-
Signal.trap(signal) { exit }
|
108
|
-
end
|
132
|
+
%w(INT TERM HUP CHLD).each {|signal| Signal.trap(signal) { exit }}
|
109
133
|
end
|
110
134
|
end # Backend
|
111
135
|
end # Pastry
|