yahns 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Documentation/yahns-rackup.txt +2 -2
- data/Documentation/yahns.txt +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/HACKING +2 -2
- data/README +7 -5
- data/extras/exec_cgi.rb +4 -2
- data/lib/yahns/fdmap.rb +1 -0
- data/lib/yahns/queue_kqueue.rb +3 -3
- data/lib/yahns/server.rb +6 -2
- data/lib/yahns/server_mp.rb +10 -9
- data/lib/yahns/sigevent_efd.rb +1 -1
- data/lib/yahns/sigevent_pipe.rb +1 -1
- data/lib/yahns/worker.rb +33 -4
- data/test/server_helper.rb +1 -0
- data/test/test_server.rb +1 -0
- data/test/test_wbuf.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cc5928f1f563c752e54bb5facb8c9a0ca63bcd1
|
4
|
+
data.tar.gz: 4aced2fa3dbe3e094f724961ce9d840e7ce4d44f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 939413895994a570e99fc3d5efa2b7513787ea9a22f40d6ab746778a62c664da079d76a3808bbd4e25a0fd65d7a0e6f38db2b96a3b74cd527e0d305ce464d04a
|
7
|
+
data.tar.gz: 2dabbe0e008fb38b2b9cad8cdc0097565dcaa179ba53ee0bb8266a7f1e737634467f7b0ddc05913acd98f14c465274194129c1258bb5394dfa0557e12f7d9a07
|
@@ -132,7 +132,7 @@ See rackup documentation for more details.
|
|
132
132
|
|
133
133
|
# CONTACT
|
134
134
|
|
135
|
-
All feedback welcome via plain-text mail to <yahns-public@
|
135
|
+
All feedback welcome via plain-text mail to <yahns-public@yhbt.net>\
|
136
136
|
No subscription is necessary to post to the mailing list.
|
137
137
|
|
138
138
|
# COPYRIGHT
|
@@ -148,5 +148,5 @@ yahns(1), yahns_config(5)
|
|
148
148
|
* [Rack RDoc][1]
|
149
149
|
* [Rackup HowTo][2]
|
150
150
|
|
151
|
-
[1]: http://
|
151
|
+
[1]: http://rdoc.info/gems/r#/gems/rack/frames
|
152
152
|
[2]: http://wiki.github.com/rack/rack/tutorial-rackup-howto
|
data/Documentation/yahns.txt
CHANGED
@@ -55,7 +55,7 @@ See yahns_config(5) for documentation on the configuration file format.
|
|
55
55
|
|
56
56
|
# CONTACT
|
57
57
|
|
58
|
-
All feedback welcome via plain-text mail to <yahns-public@
|
58
|
+
All feedback welcome via plain-text mail to <yahns-public@yhbt.net>\
|
59
59
|
No subscription is necessary to post to the mailing list.
|
60
60
|
|
61
61
|
# COPYRIGHT
|
data/GIT-VERSION-GEN
CHANGED
data/HACKING
CHANGED
@@ -46,10 +46,10 @@ contact
|
|
46
46
|
|
47
47
|
We use git(7) and develop yahns on a public mailing list like git
|
48
48
|
developers do. Please send patches via git-send-email(1) to the public
|
49
|
-
mailing list at <yahns-public@
|
49
|
+
mailing list at <yahns-public@yhbt.net>. Pull requests should be
|
50
50
|
formatted using git-request-pull(1).
|
51
51
|
|
52
|
-
Mailing list archives: http://
|
52
|
+
Mailing list archives: http://yhbt.net/yahns-public/
|
53
53
|
No subscription is necessary to post to the mailing list.
|
54
54
|
Please remember to Cc: all recipients.
|
55
55
|
|
data/README
CHANGED
@@ -56,17 +56,19 @@ Contact
|
|
56
56
|
|
57
57
|
We are happy to see feedback of all types via plain-text email.
|
58
58
|
Please send comments, user/dev discussion, patches, bug reports,
|
59
|
-
and pull requests to the public mailing list at:
|
59
|
+
and pull requests to the public inbox/mailing list at:
|
60
60
|
|
61
|
-
yahns-public@
|
61
|
+
yahns-public@yhbt.net
|
62
62
|
|
63
63
|
No subscription is necessary to post. Please Cc: all recipients as
|
64
64
|
subscription is not necessary.
|
65
65
|
|
66
|
-
You may subscribe by sending
|
66
|
+
You may subscribe by sending an email to:
|
67
67
|
|
68
|
-
yahns-public
|
69
|
-
|
68
|
+
yahns-public+subscribe@yhbt.net
|
69
|
+
|
70
|
+
You may also subscribe to the public-inbox at git://yhbt.net/yahns-public
|
71
|
+
using ssoma <http://ssoma.public-inbox.org/>
|
70
72
|
|
71
73
|
This README is our homepage, we would rather be working on HTTP servers
|
72
74
|
all day than worrying about the next browser vulnerability because
|
data/extras/exec_cgi.rb
CHANGED
@@ -62,9 +62,11 @@ class ExecCgi
|
|
62
62
|
SERVER_PORT
|
63
63
|
SERVER_PROTOCOL
|
64
64
|
SERVER_SOFTWARE
|
65
|
+
SCRIPT_NAME
|
65
66
|
).map(&:freeze) # frozen strings are faster for Hash assignments
|
66
67
|
|
67
68
|
def initialize(*args)
|
69
|
+
@env = Hash === args[0] ? args.shift : {}
|
68
70
|
@args = args
|
69
71
|
first = args[0] or
|
70
72
|
raise ArgumentError, "need path to executable"
|
@@ -75,12 +77,12 @@ class ExecCgi
|
|
75
77
|
|
76
78
|
# Calls the app
|
77
79
|
def call(env)
|
78
|
-
cgi_env = { "
|
80
|
+
cgi_env = { "GATEWAY_INTERFACE" => "CGI/1.1" }
|
79
81
|
PASS_VARS.each { |key| val = env[key] and cgi_env[key] = val }
|
80
82
|
env.each { |key,val| cgi_env[key] = val if key =~ /\AHTTP_/ }
|
81
83
|
pipe = MyIO.pipe
|
82
84
|
errbody = pipe[0]
|
83
|
-
errbody.my_pid = Process.spawn(cgi_env, *@args,
|
85
|
+
errbody.my_pid = Process.spawn(cgi_env.merge!(@env), *@args,
|
84
86
|
out: pipe[1], close_others: true)
|
85
87
|
pipe[1].close
|
86
88
|
pipe = pipe[0]
|
data/lib/yahns/fdmap.rb
CHANGED
@@ -79,6 +79,7 @@ class Yahns::Fdmap # :nodoc:
|
|
79
79
|
# We should not be calling this too frequently, it is expensive
|
80
80
|
# This is called while @fdmap_mtx is held
|
81
81
|
def __expire(timeout)
|
82
|
+
return if @count == 0
|
82
83
|
nr = 0
|
83
84
|
now = Time.now.to_f
|
84
85
|
(now - @last_expire) >= 1.0 or return # don't expire too frequently
|
data/lib/yahns/queue_kqueue.rb
CHANGED
@@ -26,7 +26,7 @@ class Yahns::Queue < SleepyPenguin::Kqueue::IO # :nodoc:
|
|
26
26
|
# flags: QEV_RD/QEV_WR (usually QEV_RD)
|
27
27
|
def queue_add(io, flags)
|
28
28
|
# order is very important here, this thread cannot do anything with
|
29
|
-
# io once we've issued
|
29
|
+
# io once we've issued kevent EV_ADD because another thread may use it
|
30
30
|
@fdmap.add(io)
|
31
31
|
fflags = ADD_ONESHOT
|
32
32
|
if flags == QEV_QUIT
|
@@ -54,8 +54,8 @@ class Yahns::Queue < SleepyPenguin::Kqueue::IO # :nodoc:
|
|
54
54
|
begin
|
55
55
|
kevent(nil, max_events) do |_,_,_,_,_,io| # don't care for flags for now
|
56
56
|
# Note: we absolutely must not do anything with io after
|
57
|
-
# we've called
|
58
|
-
# thread only until
|
57
|
+
# we've called kevent(...,EV_ADD) on it, io is exclusive to this
|
58
|
+
# thread only until kevent(...,EV_ADD) is called on it.
|
59
59
|
case rv = io.yahns_step
|
60
60
|
when :wait_readable
|
61
61
|
kevent(Kevent[io.fileno, QEV_RD, ADD_ONESHOT, 0, 0, io])
|
data/lib/yahns/server.rb
CHANGED
@@ -203,7 +203,11 @@ class Yahns::Server # :nodoc:
|
|
203
203
|
|
204
204
|
def daemon_ready
|
205
205
|
@daemon_pipe.respond_to?(:syswrite) or return
|
206
|
-
|
206
|
+
begin
|
207
|
+
@daemon_pipe.syswrite("#$$")
|
208
|
+
rescue => e
|
209
|
+
@logger.warn("grandparent died too soon?: #{e.message} (#{e.class})")
|
210
|
+
end
|
207
211
|
@daemon_pipe.close
|
208
212
|
@daemon_pipe = true # for SIGWINCH
|
209
213
|
end
|
@@ -281,7 +285,7 @@ class Yahns::Server # :nodoc:
|
|
281
285
|
@logger.info "reloading config_file=#{@config.config_file}"
|
282
286
|
@config.config_reload!
|
283
287
|
@config.commit!(self)
|
284
|
-
|
288
|
+
soft_kill_each_worker("QUIT")
|
285
289
|
Yahns::Log.reopen_all
|
286
290
|
@logger.info "done reloading config_file=#{@config.config_file}"
|
287
291
|
rescue StandardError, LoadError, SyntaxError => e
|
data/lib/yahns/server_mp.rb
CHANGED
@@ -7,14 +7,15 @@ module Yahns::ServerMP # :nodoc:
|
|
7
7
|
def maintain_worker_count
|
8
8
|
(off = @workers.size - @worker_processes) == 0 and return
|
9
9
|
off < 0 and return spawn_missing_workers
|
10
|
-
@workers.
|
11
|
-
worker.nr >= @worker_processes and
|
10
|
+
@workers.each_value do |worker|
|
11
|
+
worker.nr >= @worker_processes and worker.soft_kill(Signal.list["QUIT"])
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
16
|
-
def
|
17
|
-
|
15
|
+
# fakes delivery of a signal to each worker
|
16
|
+
def soft_kill_each_worker(sig)
|
17
|
+
sig = Signal.list[sig]
|
18
|
+
@workers.each_value { |worker| worker.soft_kill(sig) }
|
18
19
|
end
|
19
20
|
|
20
21
|
# this is the first thing that runs after forking in a child
|
@@ -94,18 +95,18 @@ module Yahns::ServerMP # :nodoc:
|
|
94
95
|
case @sig_queue.shift
|
95
96
|
when *EXIT_SIGS # graceful shutdown (twice for non graceful)
|
96
97
|
@listeners.each(&:close).clear
|
97
|
-
|
98
|
+
soft_kill_each_worker("QUIT")
|
98
99
|
state = :QUIT
|
99
100
|
when :USR1 # rotate logs
|
100
101
|
usr1_reopen("master ")
|
101
|
-
|
102
|
+
soft_kill_each_worker("USR1")
|
102
103
|
when :USR2 # exec binary, stay alive in case something went wrong
|
103
104
|
reexec
|
104
105
|
when :WINCH
|
105
106
|
if @daemon_pipe
|
106
107
|
state = :WINCH
|
107
108
|
@logger.info "gracefully stopping all workers"
|
108
|
-
|
109
|
+
soft_kill_each_worker("QUIT")
|
109
110
|
@worker_processes = 0
|
110
111
|
else
|
111
112
|
@logger.info "SIGWINCH ignored because we're not daemonized"
|
@@ -157,7 +158,7 @@ module Yahns::ServerMP # :nodoc:
|
|
157
158
|
# not performance critical
|
158
159
|
watch.delete_if { |io| io.to_io.closed? }
|
159
160
|
if r = IO.select(watch, nil, nil, alive ? nil : 0.01)
|
160
|
-
r[0].each
|
161
|
+
r[0].each(&:yahns_step)
|
161
162
|
end
|
162
163
|
case @sig_queue.shift
|
163
164
|
when *EXIT_SIGS
|
data/lib/yahns/sigevent_efd.rb
CHANGED
data/lib/yahns/sigevent_pipe.rb
CHANGED
data/lib/yahns/worker.rb
CHANGED
@@ -23,15 +23,44 @@ class Yahns::Worker # :nodoc:
|
|
23
23
|
# This causes the worker to gracefully exit if the master
|
24
24
|
# dies unexpectedly.
|
25
25
|
def yahns_step
|
26
|
-
|
27
|
-
|
26
|
+
case buf = @to_io.kgio_tryread(4)
|
27
|
+
when String
|
28
|
+
# unpack the buffer and trigger the signal handler
|
29
|
+
signum = buf.unpack('l')
|
30
|
+
fake_sig(signum[0])
|
31
|
+
# keep looping, more signals may be queued
|
32
|
+
when nil # EOF: master died, but we are at a safe place to exit
|
33
|
+
fake_sig(:QUIT)
|
28
34
|
@to_io.close
|
29
|
-
|
30
|
-
:
|
35
|
+
return :ignore
|
36
|
+
when :wait_readable # keep waiting
|
37
|
+
return :ignore
|
38
|
+
end while true # loop, as multiple signals may be sent
|
31
39
|
end
|
32
40
|
|
33
41
|
# worker objects may be compared to just plain Integers
|
34
42
|
def ==(other_nr) # :nodoc:
|
35
43
|
@nr == other_nr
|
36
44
|
end
|
45
|
+
|
46
|
+
# call a signal handler immediately without triggering EINTR
|
47
|
+
# We do not use the more obvious Process.kill(sig, $$) here since
|
48
|
+
# that signal delivery may be deferred. We want to avoid signal delivery
|
49
|
+
# while the Rack app.call is running because some database drivers
|
50
|
+
# (e.g. ruby-pg) may cancel pending requests.
|
51
|
+
def fake_sig(sig) # :nodoc:
|
52
|
+
old_cb = trap(sig, "IGNORE")
|
53
|
+
old_cb.call
|
54
|
+
ensure
|
55
|
+
trap(sig, old_cb)
|
56
|
+
end
|
57
|
+
|
58
|
+
# master sends fake signals to children
|
59
|
+
def soft_kill(signum) # :nodoc:
|
60
|
+
# writing and reading 4 bytes on a pipe is atomic on all POSIX platforms
|
61
|
+
# Do not care in the odd case the buffer is full, here.
|
62
|
+
@wr.kgio_trywrite([signum].pack('l'))
|
63
|
+
rescue Errno::EPIPE
|
64
|
+
# worker will be reaped soon
|
65
|
+
end
|
37
66
|
end
|
data/test/server_helper.rb
CHANGED
data/test/test_server.rb
CHANGED
data/test/test_wbuf.rb
CHANGED
@@ -15,6 +15,7 @@ class TestWbuf < Testcase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_wbuf
|
18
|
+
skip "sendfile not Linux-compatible" if RUBY_PLATFORM !~ /linux/
|
18
19
|
buf = "*" * (16384 * 2)
|
19
20
|
nr = 1000
|
20
21
|
[ true, false ].each do |persist|
|
@@ -59,6 +60,7 @@ class TestWbuf < Testcase
|
|
59
60
|
|
60
61
|
def test_wbuf_blocked
|
61
62
|
a, b = socketpair
|
63
|
+
skip "sendfile not Linux-compatible" if RUBY_PLATFORM !~ /linux/
|
62
64
|
buf = "." * 4096
|
63
65
|
4.times do
|
64
66
|
begin
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yahns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yahns hackers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kgio
|