rhebok 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a836851c9ccb94d821b8987477c7d40fdb1f15b0
4
- data.tar.gz: 74aaeb694d767ccf0636110e75eaaf43dbf91d07
3
+ metadata.gz: 62de5b0358298e1e28e289b07234b31d1f7ecd45
4
+ data.tar.gz: 9e1abac8fe69c3876717ef143c3c4f2e5ba8a065
5
5
  SHA512:
6
- metadata.gz: 4cc4fcfc51987e96d998e3e5314c00b8b59c9661169f814e2ed31e7b10f91d4b8b03c45ad04a91946dd919ba2f4a06c0ced3b806a13bd2dbe3338412ab0d4d7e
7
- data.tar.gz: e80fb4df159602fe5988983d26661b712ed694388a91b5b6d6c3932abf519ed33800c95a8e1e0c2f5d027ccd0904b5d36bd59d2a383341790fb6811bfe954a11
6
+ metadata.gz: 67a54bf9fb0820178c01a5a9c60678ce40883f3c47d02ceb4ab8e3bf75c9bd3edf9e77b3e03e86032f0b296fefc42807eecd94beb56e2a5a6fb883bc6a2e9dfa
7
+ data.tar.gz: 04b4648772b4e6fb723786337c10cdab5170d5357002eef7aa9b1ce6555354f15b33680fd3f88f0748c9612ab691e2b50741efbe4aa063af470d1587c2808833
data/Changes CHANGED
@@ -1,3 +1,7 @@
1
+ 0.0.6 2014-12-24T13:19:50Z
2
+
3
+ - support OobGC
4
+
1
5
  0.0.5 2014-12-19T11:06:28Z
2
6
 
3
7
  - support MaxRequestPerChild=0. worker never exit.
data/README.md CHANGED
@@ -12,6 +12,7 @@ Rhebok supports following features.
12
12
  - prefork and graceful shutdown using prefork_engine
13
13
  - hot deploy and unix domain socket using start_server
14
14
  - only supports HTTP/1.0. But does not support Keepalive.
15
+ - supports OobGC
15
16
 
16
17
  This server is suitable for running HTTP application servers behind a reverse proxy like nginx.
17
18
 
@@ -33,7 +34,7 @@ Or install it yourself as:
33
34
 
34
35
  ## Usage
35
36
 
36
- $ rackup -s Rhebok -O Port=8080 -O MaxWorkers=10 -O MaxRequestPerChild=1000 -E production config.ru
37
+ $ rackup -s Rhebok -O Port=8080 -O MaxWorkers=10 -O MaxRequestPerChild=1000 -O OobGC=yes -E production config.ru
37
38
 
38
39
  ## Sample configuration with Nginx
39
40
 
@@ -74,7 +75,7 @@ number of worker processes (default: 10)
74
75
 
75
76
  ### MaxRequestPerChild
76
77
 
77
- max. number of requests to be handled before a worker process exits (default: 1000)
78
+ Max number of requests to be handled before a worker process exits (default: 1000)
78
79
  If set to `0`. worker never exists. This option looks like Apache's MaxRequestPerChild
79
80
 
80
81
  ### MinRequestPerChild
@@ -85,6 +86,20 @@ if set, randomizes the number of requests handled by a single worker process bet
85
86
 
86
87
  seconds until timeout (default: 300)
87
88
 
89
+ ### OobGC
90
+
91
+ Boolean like string. If true, Rhebok execute GC after close client socket. (defualt: false)
92
+
93
+ ### MaxGCPerRequest
94
+
95
+ If [gctools](https://github.com/tmm1/gctools) is available, this option is not used. invoke GC by `GC::OOB.run` after every requests.
96
+
97
+ Max number of request before invoking GC (defualt: 5)
98
+
99
+ ### MinGCPerRequest
100
+
101
+ If set, randomizes the number of request before invoking GC between the number of MaxGCPerRequest (defualt: none)
102
+
88
103
  ### SpawnInterval
89
104
 
90
105
  if set, worker processes will not be spawned more than once than every given seconds. Also, when SIGHUP is being received, no more than one worker processes will be collected every given seconds. This feature is useful for doing a "slow-restart". See http://blog.kazuhooku.com/2011/04/web-serverstarter-parallelprefork.html for more information. (default: none)
@@ -11,6 +11,13 @@ require 'io/nonblock'
11
11
  require 'prefork_engine'
12
12
  require 'rhebok'
13
13
 
14
+ $RACK_HANDLER_RHEBOK_GCTOOL = true
15
+ begin
16
+ require 'gctools/oobgc'
17
+ rescue LoadError
18
+ $RACK_HANDLER_RHEBOK_GCTOOL = false
19
+ end
20
+
14
21
  module Rack
15
22
  module Handler
16
23
  class Rhebok
@@ -23,7 +30,10 @@ module Rack
23
30
  :MaxRequestPerChild => 1000,
24
31
  :MinRequestPerChild => nil,
25
32
  :SpawnInterval => nil,
26
- :ErrRespawnInterval => nil
33
+ :ErrRespawnInterval => nil,
34
+ :OobGC => false,
35
+ :MaxGCPerRequest => 5,
36
+ :MinGCPerRequest => nil,
27
37
  }
28
38
  NULLIO = StringIO.new("").set_encoding('BINARY')
29
39
 
@@ -41,16 +51,20 @@ module Rack
41
51
  end
42
52
 
43
53
  def initialize(options={})
54
+ if options[:OobGC].instance_of?(String)
55
+ options[:OobGC] = options[:OobGC].match(/^(true|yes|1)$/i) ? true : false
56
+ end
44
57
  @options = DEFAULT_OPTIONS.merge(options)
58
+ p @options[:OobGC]
45
59
  @server = nil
46
60
  @_is_tcp = false
47
61
  @_using_defer_accept = false
48
62
  end
49
63
 
50
64
  def setup_listener()
51
- if ENV["SERVER_STARTER_PORT"] then
65
+ if ENV["SERVER_STARTER_PORT"]
52
66
  hostport, fd = ENV["SERVER_STARTER_PORT"].split("=",2)
53
- if m = hostport.match(/(.*):(\d+)/) then
67
+ if m = hostport.match(/(.*):(\d+)/)
54
68
  @options[:Host] = m[0]
55
69
  @options[:Port] = m[1].to_i
56
70
  else
@@ -67,7 +81,7 @@ module Rack
67
81
  @_is_tcp = true
68
82
  end
69
83
 
70
- if RUBY_PLATFORM.match(/linux/) && @_is_tcp == true then
84
+ if RUBY_PLATFORM.match(/linux/) && @_is_tcp == true
71
85
  begin
72
86
  @server.setsockopt(Socket::IPPROTO_TCP, 9, 1)
73
87
  @_using_defer_accept = true
@@ -83,49 +97,68 @@ module Rack
83
97
  "HUP" => 'TERM',
84
98
  },
85
99
  }
86
- if @options[:SpawnInterval] then
100
+ if @options[:SpawnInterval]
87
101
  pm_args["trap_signals"]["USR1"] = ["TERM", @options[:SpawnInterval].to_i]
88
102
  pm_args["spawn_interval"] = @options[:SpawnInterval].to_i
89
103
  end
90
- if @options[:ErrRespawnInterval] then
104
+ if @options[:ErrRespawnInterval]
91
105
  pm_args["err_respawn_interval"] = @options[:ErrRespawnInterval].to_i
92
106
  end
93
107
  Signal.trap('INT','SYSTEM_DEFAULT') # XXX
94
108
 
95
109
  pe = PreforkEngine.new(pm_args)
96
110
  while !pe.signal_received.match(/^(TERM|USR1)$/)
97
- pe.start {
98
- srand
111
+ pe.start do
112
+ srand
99
113
  self.accept_loop(app)
100
- }
114
+ end
101
115
  end
102
116
  pe.wait_all_children
103
117
  end
104
118
 
105
119
  def _calc_reqs_per_child
120
+ if @options[:MinRequestPerChild] == nil
121
+ return @options[:MaxRequestPerChild].to_i
122
+ end
106
123
  max = @options[:MaxRequestPerChild].to_i
107
- if min = @options[:MinRequestPerChild] then
108
- return max.to_i if min.to_i >= max
109
- return (max - (max - min.to_i + 1) * rand).to_i
124
+ min = @options[:MinRequestPerChild].to_i
125
+ if min < max
126
+ max - ((max - min + 1) * rand).to_i
127
+ else
128
+ max
110
129
  end
111
- return max
112
130
  end
113
131
 
132
+ def _calc_gc_per_req
133
+ if @options[:MinGCPerRequest] == nil
134
+ return @options[:MaxGCPerRequest].to_i
135
+ end
136
+ max = @options[:MaxGCPerRequest].to_i
137
+ min = @options[:MinGCPerRequest].to_i
138
+ if min < max
139
+ max - ((max - min + 1) * rand).to_i
140
+ else
141
+ max
142
+ end
143
+ end
144
+
145
+
114
146
  def accept_loop(app)
115
147
  @can_exit = true
116
148
  @term_received = 0
117
149
  proc_req_count = 0
118
150
  Signal.trap(:TERM) do
119
151
  @term_received += 1
120
- if @can_exit then
152
+ if @can_exit
121
153
  exit!(true)
122
154
  end
123
- if @can_exit || @term_received > 1 then
155
+ if @can_exit || @term_received > 1
124
156
  exit!(true)
125
157
  end
126
158
  end
127
159
  Signal.trap(:PIPE, "IGNORE")
128
160
  max_reqs = self._calc_reqs_per_child()
161
+ gc_reqs = self._calc_gc_per_req()
129
162
  fileno = @server.fileno
130
163
 
131
164
  env_template = {
@@ -144,15 +177,15 @@ module Rack
144
177
  @can_exit = true
145
178
  env = env_template.clone
146
179
  connection, buf = ::Rhebok.accept_rack(fileno, @options[:Timeout], @_is_tcp, env)
147
- if connection then
180
+ if connection
148
181
  # for tempfile
149
182
  buffer = nil
150
183
  begin
151
184
  proc_req_count += 1
152
185
  @can_exit = false
153
186
  # handle request
154
- if env.key?("CONTENT_LENGTH") && env["CONTENT_LENGTH"].to_i > 0 then
155
- cl = env["CONTENT_LENGTH"].to_i;
187
+ if env.key?("CONTENT_LENGTH") && env["CONTENT_LENGTH"].to_i > 0
188
+ cl = env["CONTENT_LENGTH"].to_i
156
189
  if cl > MAX_MEMORY_BUFFER_SIZE
157
190
  buffer = Tempfile.open('r')
158
191
  buffer.binmode
@@ -162,12 +195,12 @@ module Rack
162
195
  end
163
196
  while cl > 0
164
197
  chunk = ""
165
- if buf.bytesize > 0 then
198
+ if buf.bytesize > 0
166
199
  chunk = buf
167
200
  buf = ""
168
201
  else
169
202
  readed = ::Rhebok.read_timeout(connection, chunk, cl, 0, @options[:Timeout])
170
- if readed == nil then
203
+ if readed == nil
171
204
  return
172
205
  end
173
206
  end
@@ -179,13 +212,13 @@ module Rack
179
212
  end
180
213
 
181
214
  status_code, headers, body = app.call(env)
182
- if body.instance_of?(Array) then
215
+ if body.instance_of?(Array)
183
216
  ::Rhebok.write_response(connection, @options[:Timeout], status_code, headers, body)
184
217
  else
185
218
  ::Rhebok.write_response(connection, @options[:Timeout], status_code, headers, [])
186
219
  body.each do |part|
187
220
  ret = ::Rhebok.write_all(connection, part, 0, @options[:Timeout])
188
- if ret == nil then
221
+ if ret == nil
189
222
  break
190
223
  end
191
224
  end #body.each
@@ -196,9 +229,19 @@ module Rack
196
229
  buffer.close!
197
230
  end
198
231
  ::Rhebok.close_rack(connection)
232
+ # out of band gc
233
+ if @options[:OobGC]
234
+ if $RACK_HANDLER_RHEBOK_GCTOOL
235
+ GC::OOB.run
236
+ elsif proc_req_count % gc_reqs == 0
237
+ disabled = GC.enable
238
+ GC.start
239
+ GC.disable if disabled
240
+ end
241
+ end
199
242
  end #begin
200
243
  end # accept
201
- if @term_received > 0 then
244
+ if @term_received > 0
202
245
  exit!(true)
203
246
  end
204
247
  end #while max_reqs
@@ -207,6 +250,3 @@ module Rack
207
250
  end
208
251
  end
209
252
  end
210
-
211
-
212
-
@@ -1,3 +1,3 @@
1
1
  class Rhebok
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhebok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nagano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-19 00:00:00.000000000 Z
11
+ date: 2014-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler