yahns 0.0.0TP1
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 +7 -0
- data/.gitignore +15 -0
- data/COPYING +674 -0
- data/GIT-VERSION-GEN +41 -0
- data/GNUmakefile +90 -0
- data/README +127 -0
- data/Rakefile +60 -0
- data/bin/yahns +32 -0
- data/examples/README +3 -0
- data/examples/init.sh +76 -0
- data/examples/logger_mp_safe.rb +28 -0
- data/examples/logrotate.conf +32 -0
- data/examples/yahns_multi.conf.rb +89 -0
- data/examples/yahns_rack_basic.conf.rb +27 -0
- data/lib/yahns.rb +73 -0
- data/lib/yahns/acceptor.rb +28 -0
- data/lib/yahns/client_expire.rb +40 -0
- data/lib/yahns/client_expire_portable.rb +39 -0
- data/lib/yahns/config.rb +344 -0
- data/lib/yahns/daemon.rb +51 -0
- data/lib/yahns/fdmap.rb +90 -0
- data/lib/yahns/http_client.rb +198 -0
- data/lib/yahns/http_context.rb +65 -0
- data/lib/yahns/http_response.rb +184 -0
- data/lib/yahns/log.rb +73 -0
- data/lib/yahns/queue.rb +7 -0
- data/lib/yahns/queue_egg.rb +23 -0
- data/lib/yahns/queue_epoll.rb +57 -0
- data/lib/yahns/rack.rb +80 -0
- data/lib/yahns/server.rb +336 -0
- data/lib/yahns/server_mp.rb +181 -0
- data/lib/yahns/sigevent.rb +7 -0
- data/lib/yahns/sigevent_efd.rb +18 -0
- data/lib/yahns/sigevent_pipe.rb +29 -0
- data/lib/yahns/socket_helper.rb +117 -0
- data/lib/yahns/stream_file.rb +34 -0
- data/lib/yahns/stream_input.rb +150 -0
- data/lib/yahns/tee_input.rb +114 -0
- data/lib/yahns/tmpio.rb +27 -0
- data/lib/yahns/wbuf.rb +36 -0
- data/lib/yahns/wbuf_common.rb +32 -0
- data/lib/yahns/worker.rb +58 -0
- data/test/covshow.rb +29 -0
- data/test/helper.rb +115 -0
- data/test/server_helper.rb +65 -0
- data/test/test_bin.rb +97 -0
- data/test/test_client_expire.rb +132 -0
- data/test/test_config.rb +56 -0
- data/test/test_fdmap.rb +19 -0
- data/test/test_output_buffering.rb +291 -0
- data/test/test_queue.rb +59 -0
- data/test/test_rack.rb +28 -0
- data/test/test_serve_static.rb +42 -0
- data/test/test_server.rb +415 -0
- data/test/test_stream_file.rb +30 -0
- data/test/test_wbuf.rb +136 -0
- data/yahns.gemspec +19 -0
- metadata +165 -0
data/GIT-VERSION-GEN
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
|
3
|
+
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
|
+
CONSTANT = "Yahns::VERSION"
|
5
|
+
RVF = "lib/yahns/version.rb"
|
6
|
+
GVF = "GIT-VERSION-FILE"
|
7
|
+
DEF_VER = "v0.0.0TP1"
|
8
|
+
vn = DEF_VER
|
9
|
+
|
10
|
+
# First see if there is a version file (included in release tarballs),
|
11
|
+
# then try git-describe, then default.
|
12
|
+
if File.exist?(".git")
|
13
|
+
describe = `git describe --abbrev=4 HEAD 2>/dev/null`.strip
|
14
|
+
case describe
|
15
|
+
when /\Av[0-9]*/
|
16
|
+
vn = describe
|
17
|
+
system(*%w(git update-index -q --refresh))
|
18
|
+
unless `git diff-index --name-only HEAD --`.chomp.empty?
|
19
|
+
vn << "-dirty"
|
20
|
+
end
|
21
|
+
vn.tr!('-', '.')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
vn = vn.sub!(/\Av/, "")
|
26
|
+
new_ruby_version = "#{CONSTANT} = '#{vn}' # :nodoc:\n"
|
27
|
+
cur_ruby_version = File.read(RVF) rescue nil
|
28
|
+
if new_ruby_version != cur_ruby_version
|
29
|
+
File.open(RVF, "w") { |fp| fp.write(new_ruby_version) }
|
30
|
+
end
|
31
|
+
File.chmod(0644, RVF)
|
32
|
+
|
33
|
+
# generate the makefile snippet
|
34
|
+
new_make_version = "VERSION = #{vn}\n"
|
35
|
+
cur_make_version = File.read(GVF) rescue nil
|
36
|
+
if new_make_version != cur_make_version
|
37
|
+
File.open(GVF, "w") { |fp| fp.write(new_make_version) }
|
38
|
+
end
|
39
|
+
File.chmod(0644, GVF)
|
40
|
+
|
41
|
+
puts vn if $0 == __FILE__
|
data/GNUmakefile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
|
2
|
+
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
+
all::
|
4
|
+
pkg = yahns
|
5
|
+
RUBY = ruby
|
6
|
+
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
7
|
+
@./GIT-VERSION-GEN
|
8
|
+
-include GIT-VERSION-FILE
|
9
|
+
lib := lib
|
10
|
+
|
11
|
+
all:: test
|
12
|
+
test_units := $(wildcard test/test_*.rb)
|
13
|
+
test: $(test_units)
|
14
|
+
$(test_units):
|
15
|
+
$(RUBY) -w -I $(lib) $@ -v
|
16
|
+
|
17
|
+
test-mt: export N = $(shell nproc 2>/dev/null || echo 4)
|
18
|
+
test-mt:
|
19
|
+
$(RUBY) -w -I $(lib) $(addprefix -r./,$(test_units)) -eexit --
|
20
|
+
|
21
|
+
check-warnings:
|
22
|
+
@(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
|
23
|
+
do $(RUBY) -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
|
24
|
+
|
25
|
+
check: test
|
26
|
+
coverage: export COVERAGE=1
|
27
|
+
coverage:
|
28
|
+
> coverage.dump
|
29
|
+
$(MAKE) check
|
30
|
+
$(RUBY) ./test/covshow.rb
|
31
|
+
|
32
|
+
coverage-mt: export COVERAGE=1
|
33
|
+
coverage-mt:
|
34
|
+
> coverage.dump
|
35
|
+
$(MAKE) test-mt
|
36
|
+
$(RUBY) ./test/covshow.rb
|
37
|
+
|
38
|
+
pkggem := pkg/$(pkg)-$(VERSION).gem
|
39
|
+
pkgtgz := pkg/$(pkg)-$(VERSION).tar.gz
|
40
|
+
|
41
|
+
fix-perms:
|
42
|
+
git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644
|
43
|
+
git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755
|
44
|
+
|
45
|
+
gem: $(pkggem)
|
46
|
+
|
47
|
+
install-gem: $(pkggem)
|
48
|
+
gem install $(CURDIR)/$<
|
49
|
+
|
50
|
+
$(pkggem): .gem-manifest
|
51
|
+
VERSION=$(VERSION) gem build $(pkg).gemspec
|
52
|
+
mkdir -p pkg
|
53
|
+
mv $(@F) $@
|
54
|
+
|
55
|
+
pkg_extra := GIT-VERSION-FILE lib/yahns/version.rb NEWS
|
56
|
+
NEWS:
|
57
|
+
rake -s $@
|
58
|
+
|
59
|
+
gem-man:
|
60
|
+
$(MAKE) -C Documentation/ gem-man
|
61
|
+
tgz-man:
|
62
|
+
$(MAKE) -C Documentation/ install-man mandir=$(CURDIR)/man
|
63
|
+
.PHONY: tgz-man gem-man
|
64
|
+
|
65
|
+
.gem-manifest: .manifest
|
66
|
+
# (ls man/*.?; cat .manifest) | LC_ALL=C sort > $@+
|
67
|
+
LC_ALL=C sort < .manifest > $@+
|
68
|
+
cmp $@+ $@ || mv $@+ $@; rm -f $@+
|
69
|
+
.tgz-manifest: .manifest
|
70
|
+
LC_ALL=C sort < .manifest > $@+
|
71
|
+
cmp $@+ $@ || mv $@+ $@; rm -f $@+
|
72
|
+
.manifest: NEWS fix-perms
|
73
|
+
rm -rf man
|
74
|
+
(git ls-files; \
|
75
|
+
for i in $(pkg_extra); do echo $$i; done) | \
|
76
|
+
LC_ALL=C sort > $@+
|
77
|
+
cmp $@+ $@ || mv $@+ $@; rm -f $@+
|
78
|
+
$(pkgtgz): distdir = pkg/$(pkg)-$(VERSION)
|
79
|
+
$(pkgtgz): .tgz-manifest
|
80
|
+
@test -n "$(distdir)"
|
81
|
+
$(RM) -r $(distdir)
|
82
|
+
mkdir -p $(distdir)
|
83
|
+
tar cf - $$(cat .tgz-manifest) | (cd $(distdir) && tar xf -)
|
84
|
+
cd pkg && tar cf - $(pkg)-$(VERSION) | gzip -9 > $(@F)+
|
85
|
+
mv $@+ $@
|
86
|
+
|
87
|
+
package: $(pkgtgz) $(pkggem)
|
88
|
+
|
89
|
+
.PHONY: all .FORCE-GIT-VERSION-FILE test $(test_units) NEWS
|
90
|
+
.PHONY: check-warnings fix-perms
|
data/README
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
yahns - sleepy, multi-threaded, non-blocking application server for Ruby
|
2
|
+
------------------------------------------------------------------------
|
3
|
+
|
4
|
+
A Free Software, multi-threaded, non-blocking network application server
|
5
|
+
designed for low _idle_ power consumption. It is primarily optimized
|
6
|
+
for applications with occasional users which see little or no traffic.
|
7
|
+
yahns currently hosts Rack/HTTP applications, but may eventually support
|
8
|
+
other application types. Unlike some existing servers, yahns is
|
9
|
+
extremely sensitive to fatal bugs in the applications it hosts.
|
10
|
+
|
11
|
+
Features
|
12
|
+
--------
|
13
|
+
|
14
|
+
* _zero_ wakeups when all clients are idle
|
15
|
+
* idle client connections may live forever if there is no FD pressure
|
16
|
+
* suitable for slow clients, fast clients, or a mixture of both
|
17
|
+
* HTTP/0.9 support
|
18
|
+
* HTTP/1.1 persistent connections and pipelining
|
19
|
+
* decodes HTTP chunked encoding for requests
|
20
|
+
* parses HTTP/1.1 trailers in requests
|
21
|
+
* supports streaming responses with lazy buffering for slow clients
|
22
|
+
* optional streaming input for fast clients
|
23
|
+
* able to host multiple applications with different settings
|
24
|
+
* uses epoll to scale to many idle connections
|
25
|
+
* abuses epoll as a load balancer between threads inside a process
|
26
|
+
* optional multi-process support (in addition to threads)
|
27
|
+
* fairly balances new clients between multiple processes (on Linux)
|
28
|
+
|
29
|
+
Supported Platforms
|
30
|
+
-------------------
|
31
|
+
|
32
|
+
yahns is developed primarily for modern GNU/Linux systems.
|
33
|
+
|
34
|
+
We may support kqueue for FreeBSD/OpenBSD/NetBSD if there is significant
|
35
|
+
interest. Non-Free systems/dependencies will never be supported
|
36
|
+
|
37
|
+
Supported Ruby implementations:
|
38
|
+
* (Matz) Ruby 2.0 or later
|
39
|
+
* Rubinius 2.0 or later (planned)
|
40
|
+
|
41
|
+
Contact
|
42
|
+
-------
|
43
|
+
|
44
|
+
We are happy to see feedback of all types via plain-text email.
|
45
|
+
Please send comments, user/dev discussion, patches, bug reports,
|
46
|
+
and pull requests to Eric Wong at: normalperson@yhbt.net
|
47
|
+
|
48
|
+
Public mailing list coming soon.
|
49
|
+
|
50
|
+
This README is our homepage, we would rather be working on HTTP servers
|
51
|
+
all day than worrying about the next browser vulnerability because
|
52
|
+
HTML/CSS/JS is too complicated for us.
|
53
|
+
|
54
|
+
* http://yahns.yhbt.net/README
|
55
|
+
|
56
|
+
Hacking
|
57
|
+
-------
|
58
|
+
|
59
|
+
We use git and follow the same development model as git itself
|
60
|
+
(mailing list-oriented, benevolent dictator).
|
61
|
+
|
62
|
+
git clone git://yahns.yhbt.net/yahns
|
63
|
+
|
64
|
+
Please use git-format-patch(1) and git-send-email(1) distributed with
|
65
|
+
the git(7) suite for generating and sending patches. Please format
|
66
|
+
pull requests with the git-request-pull(1) script (also distributed
|
67
|
+
with git(7)) and send them via email.
|
68
|
+
|
69
|
+
See http://www.git-scm.com/ for more information on git.
|
70
|
+
|
71
|
+
Design
|
72
|
+
------
|
73
|
+
|
74
|
+
yahns is designed to optimimally use multiple threads with non-blocking I/O.
|
75
|
+
The event loop is not a traditional single-threaded design with a mutex
|
76
|
+
slapped on as an afterthought, but designed from the beginning to utilize
|
77
|
+
multiple threads.
|
78
|
+
|
79
|
+
* two classes of long-lived, persistent threads
|
80
|
+
1. blocking acceptors
|
81
|
+
2. non-blocking event loop workers
|
82
|
+
* epoll acts as a queue (by using one-shot notifications)
|
83
|
+
* acceptors accept new clients and put them in the epoll "queue"
|
84
|
+
* workers pull clients off the queue, rearming them to epoll on EAGAIN
|
85
|
+
|
86
|
+
The end result is clients transition freely and fairly between threads
|
87
|
+
and will always be able to find the next idle thread to run on.
|
88
|
+
|
89
|
+
This design works with kqueue, too, and we will support kqueue if there
|
90
|
+
is interest. In fact, got our design inspiration from the name "kqueue"
|
91
|
+
when working on another project. We may also support libkqueue:
|
92
|
+
|
93
|
+
http://sourceforge.net/projects/libkqueue/
|
94
|
+
|
95
|
+
In addition to multiple threads, yahns optionally supports multiple
|
96
|
+
processes to work around low FD limits as well as contention in the:
|
97
|
+
|
98
|
+
* kernel (socket (de)allocation from accept/close)
|
99
|
+
* standard C library (malloc/free)
|
100
|
+
* Ruby VM (GVL, GC)
|
101
|
+
* application it hosts
|
102
|
+
|
103
|
+
Copyright
|
104
|
+
---------
|
105
|
+
|
106
|
+
Copyright 2013, Eric Wong <normalperson@yhbt.net> and all contributors.
|
107
|
+
License: GPLv3 or later <https://www.gnu.org/licenses/gpl-3.0.txt>
|
108
|
+
|
109
|
+
yahns is copyrighted Free Software by all contributors, see logs in
|
110
|
+
revision control for names and email addresses of all of them. yahns
|
111
|
+
contains code from Mongrel, unicorn, and Rainbows! which may also be
|
112
|
+
licensed under the GPLv2 or later.
|
113
|
+
|
114
|
+
yahns is free software; you can redistribute it and/or modify it
|
115
|
+
under the terms of the GNU General Public License as published by the
|
116
|
+
Free Software Foundation; either version 3 of the License, or (at your
|
117
|
+
option) any later version.
|
118
|
+
|
119
|
+
yahns is distributed in the hope that it will be useful, but WITHOUT ANY
|
120
|
+
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
121
|
+
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
122
|
+
for more details.
|
123
|
+
|
124
|
+
You should have received a copy of the GNU General Public License along
|
125
|
+
with this program; if not, see https://www.gnu.org/licenses/gpl-3.0.txt
|
126
|
+
|
127
|
+
lrg nabgure ubeevoyl-anzrq freire :>
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
|
2
|
+
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
3
|
+
require 'tempfile'
|
4
|
+
include Rake::DSL
|
5
|
+
task "NEWS" do
|
6
|
+
latest = nil
|
7
|
+
fp = Tempfile.new("NEWS", ".")
|
8
|
+
fp.sync = true
|
9
|
+
`git tag -l`.split(/\n/).reverse.each do |tag|
|
10
|
+
%r{\Av(.+)} =~ tag or next
|
11
|
+
version = $1
|
12
|
+
header, subject, body = `git cat-file tag #{tag}`.split(/\n\n/, 3)
|
13
|
+
header = header.split(/\n/)
|
14
|
+
tagger = header.grep(/\Atagger /)[0]
|
15
|
+
time = Time.at(tagger.split(/ /)[-2].to_i).utc
|
16
|
+
latest ||= time
|
17
|
+
date = time.strftime("%Y-%m-%d")
|
18
|
+
fp.puts "# #{version} / #{date}\n\n#{subject}"
|
19
|
+
if body && body.strip.size > 0
|
20
|
+
fp.puts "\n\n#{body}"
|
21
|
+
end
|
22
|
+
fp.puts
|
23
|
+
end
|
24
|
+
fp.write("Unreleased\n\n") unless fp.size > 0
|
25
|
+
fp.puts "# COPYRIGHT"
|
26
|
+
bdfl = 'Eric Wong <normalperson@yhbt.net>'
|
27
|
+
fp.puts "Copyright (C) 2013, #{bdfl} and all contributors"
|
28
|
+
fp.puts "License: GPLv3 or later (http://www.gnu.org/licenses/gpl-3.0.txt)"
|
29
|
+
fp.rewind
|
30
|
+
assert_equal fp.read, File.read("NEWS") rescue nil
|
31
|
+
fp.chmod 0644
|
32
|
+
File.rename(fp.path, "NEWS")
|
33
|
+
fp.close!
|
34
|
+
end
|
35
|
+
|
36
|
+
task rsync_docs: "NEWS" do
|
37
|
+
dest = ENV["RSYNC_DEST"] || "yahns.yhbt.net:/srv/yahns/"
|
38
|
+
top = %w(NEWS README COPYING)
|
39
|
+
files = []
|
40
|
+
|
41
|
+
# git-set-file-times is distributed with rsync,
|
42
|
+
# Also available at: http://yhbt.net/git-set-file-times
|
43
|
+
# on Debian systems: /usr/share/doc/rsync/scripts/git-set-file-times.gz
|
44
|
+
sh("git", "set-file-times", "examples", *top)
|
45
|
+
|
46
|
+
`git ls-files Documentation/*.txt`.split(/\n/).concat(top).each do |txt|
|
47
|
+
gz = "#{txt}.gz"
|
48
|
+
tmp = "#{gz}.#$$"
|
49
|
+
sh("gzip -9 < #{txt} > #{tmp}")
|
50
|
+
st = File.stat(txt)
|
51
|
+
File.utime(st.atime, st.mtime, tmp) # make nginx gzip_static happy
|
52
|
+
File.rename(tmp, gz)
|
53
|
+
files << txt
|
54
|
+
files << gz
|
55
|
+
end
|
56
|
+
sh("rsync --chmod=Fugo=r -av #{files.join(' ')} #{dest}")
|
57
|
+
|
58
|
+
examples = `git ls-files examples`.split("\n")
|
59
|
+
sh("rsync --chmod=Fugo=r -av #{examples.join(' ')} #{dest}/examples/")
|
60
|
+
end
|
data/bin/yahns
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/this/will/be/overwritten/or/wrapped/anyways/do/not/worry/ruby
|
2
|
+
# -*- encoding: binary -*-
|
3
|
+
# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
|
4
|
+
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
|
5
|
+
$stdout.sync = $stderr.sync = true
|
6
|
+
require 'yahns'
|
7
|
+
require 'optparse'
|
8
|
+
config_file = daemonize = nil
|
9
|
+
OptionParser.new("", 24, " ") do |opts|
|
10
|
+
cmd = File.basename($0)
|
11
|
+
opts.banner = "Usage: #{cmd} [options]"
|
12
|
+
opts.separator "#{cmd} options:"
|
13
|
+
opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
|
14
|
+
daemonize = !!d
|
15
|
+
end
|
16
|
+
opts.on("-c", "--config-file FILE", "yahns config file") do |f|
|
17
|
+
config_file = f
|
18
|
+
end
|
19
|
+
opts.separator "Common options:"
|
20
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
21
|
+
puts opts.to_s
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
opts.on_tail("-v", "--version", "Show version") do
|
25
|
+
puts "#{cmd} v#{Yahns::VERSION}"
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
opts.parse!(ARGV)
|
29
|
+
end
|
30
|
+
server = Yahns::Server.new(Yahns::Config.new(config_file))
|
31
|
+
Yahns::Daemon.daemon(server) if daemonize
|
32
|
+
server.start.join
|
data/examples/README
ADDED
data/examples/init.sh
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
# To the extent possible under law, Eric Wong has waived all copyright and
|
3
|
+
# related or neighboring rights to this examples
|
4
|
+
set -e
|
5
|
+
# Example init script, this can be used with nginx, too,
|
6
|
+
# since nginx and yahns accept the same signals
|
7
|
+
|
8
|
+
# Feel free to change any of the following variables for your app:
|
9
|
+
TIMEOUT=${TIMEOUT-60}
|
10
|
+
APP_ROOT=/home/x/my_app/current
|
11
|
+
PID=$APP_ROOT/tmp/pids/yahns.pid
|
12
|
+
CMD="/usr/bin/yahns -D -c $APP_ROOT/config/yahns.rb"
|
13
|
+
INIT_CONF=$APP_ROOT/config/init.conf
|
14
|
+
action="$1"
|
15
|
+
set -u
|
16
|
+
|
17
|
+
test -f "$INIT_CONF" && . $INIT_CONF
|
18
|
+
|
19
|
+
old_pid="$PID.oldbin"
|
20
|
+
|
21
|
+
cd $APP_ROOT || exit 1
|
22
|
+
|
23
|
+
sig () {
|
24
|
+
test -s "$PID" && kill -$1 `cat $PID`
|
25
|
+
}
|
26
|
+
|
27
|
+
oldsig () {
|
28
|
+
test -s $old_pid && kill -$1 `cat $old_pid`
|
29
|
+
}
|
30
|
+
|
31
|
+
case $action in
|
32
|
+
start)
|
33
|
+
sig 0 && echo >&2 "Already running" && exit 0
|
34
|
+
$CMD
|
35
|
+
;;
|
36
|
+
stop)
|
37
|
+
sig QUIT && exit 0
|
38
|
+
echo >&2 "Not running"
|
39
|
+
;;
|
40
|
+
force-stop)
|
41
|
+
sig TERM && exit 0
|
42
|
+
echo >&2 "Not running"
|
43
|
+
;;
|
44
|
+
restart|reload)
|
45
|
+
sig HUP && echo reloaded OK && exit 0
|
46
|
+
echo >&2 "Couldn't reload, starting '$CMD' instead"
|
47
|
+
$CMD
|
48
|
+
;;
|
49
|
+
upgrade)
|
50
|
+
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
|
51
|
+
then
|
52
|
+
n=$TIMEOUT
|
53
|
+
while test -s $old_pid && test $n -ge 0
|
54
|
+
do
|
55
|
+
printf '.' && sleep 1 && n=$(( $n - 1 ))
|
56
|
+
done
|
57
|
+
echo
|
58
|
+
|
59
|
+
if test $n -lt 0 && test -s $old_pid
|
60
|
+
then
|
61
|
+
echo >&2 "$old_pid still exists after $TIMEOUT seconds"
|
62
|
+
exit 1
|
63
|
+
fi
|
64
|
+
exit 0
|
65
|
+
fi
|
66
|
+
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
|
67
|
+
$CMD
|
68
|
+
;;
|
69
|
+
reopen-logs)
|
70
|
+
sig USR1
|
71
|
+
;;
|
72
|
+
*)
|
73
|
+
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
|
74
|
+
exit 1
|
75
|
+
;;
|
76
|
+
esac
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# To the extent possible under law, Eric Wong has waived all copyright and
|
2
|
+
# related or neighboring rights to this examples
|
3
|
+
#
|
4
|
+
# Multi-Processing-safe monkey patch for Logger
|
5
|
+
#
|
6
|
+
# This monkey patch fixes the case where "preload: true" is used and
|
7
|
+
# the application spawns a background thread upon being loaded.
|
8
|
+
#
|
9
|
+
# This removes all lock from the Logger code and solely relies on the
|
10
|
+
# underlying filesystem to handle write(2) system calls atomically when
|
11
|
+
# O_APPEND is used. This is safe in the presence of both multiple
|
12
|
+
# threads (native or green) and multiple processes when writing to
|
13
|
+
# a filesystem with POSIX O_APPEND semantics.
|
14
|
+
#
|
15
|
+
# It should be noted that the original locking on Logger could _never_ be
|
16
|
+
# considered reliable on non-POSIX filesystems with multiple processes,
|
17
|
+
# either, so nothing is lost in that case.
|
18
|
+
|
19
|
+
require 'logger'
|
20
|
+
class Logger::LogDevice
|
21
|
+
def write(message)
|
22
|
+
@dev.syswrite(message)
|
23
|
+
end
|
24
|
+
|
25
|
+
def close
|
26
|
+
@dev.close
|
27
|
+
end
|
28
|
+
end
|