yahns 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|