pastry 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/pastry +7 -0
  2. data/lib/pastry.rb +42 -18
  3. 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
- # TODO: validation
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 #{@app} pastry with #{pool} flakes listening on #{unix ? 'socket %s ' % unix : 'port %d' % port}"
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
- pids = pool.times.map { run(server) }
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
- unless @running
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 << run(server)
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 { EM.run { Backend.new.start(server) } }
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 do |signal|
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
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bharanee Rathna