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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/COPYING +674 -0
  4. data/GIT-VERSION-GEN +41 -0
  5. data/GNUmakefile +90 -0
  6. data/README +127 -0
  7. data/Rakefile +60 -0
  8. data/bin/yahns +32 -0
  9. data/examples/README +3 -0
  10. data/examples/init.sh +76 -0
  11. data/examples/logger_mp_safe.rb +28 -0
  12. data/examples/logrotate.conf +32 -0
  13. data/examples/yahns_multi.conf.rb +89 -0
  14. data/examples/yahns_rack_basic.conf.rb +27 -0
  15. data/lib/yahns.rb +73 -0
  16. data/lib/yahns/acceptor.rb +28 -0
  17. data/lib/yahns/client_expire.rb +40 -0
  18. data/lib/yahns/client_expire_portable.rb +39 -0
  19. data/lib/yahns/config.rb +344 -0
  20. data/lib/yahns/daemon.rb +51 -0
  21. data/lib/yahns/fdmap.rb +90 -0
  22. data/lib/yahns/http_client.rb +198 -0
  23. data/lib/yahns/http_context.rb +65 -0
  24. data/lib/yahns/http_response.rb +184 -0
  25. data/lib/yahns/log.rb +73 -0
  26. data/lib/yahns/queue.rb +7 -0
  27. data/lib/yahns/queue_egg.rb +23 -0
  28. data/lib/yahns/queue_epoll.rb +57 -0
  29. data/lib/yahns/rack.rb +80 -0
  30. data/lib/yahns/server.rb +336 -0
  31. data/lib/yahns/server_mp.rb +181 -0
  32. data/lib/yahns/sigevent.rb +7 -0
  33. data/lib/yahns/sigevent_efd.rb +18 -0
  34. data/lib/yahns/sigevent_pipe.rb +29 -0
  35. data/lib/yahns/socket_helper.rb +117 -0
  36. data/lib/yahns/stream_file.rb +34 -0
  37. data/lib/yahns/stream_input.rb +150 -0
  38. data/lib/yahns/tee_input.rb +114 -0
  39. data/lib/yahns/tmpio.rb +27 -0
  40. data/lib/yahns/wbuf.rb +36 -0
  41. data/lib/yahns/wbuf_common.rb +32 -0
  42. data/lib/yahns/worker.rb +58 -0
  43. data/test/covshow.rb +29 -0
  44. data/test/helper.rb +115 -0
  45. data/test/server_helper.rb +65 -0
  46. data/test/test_bin.rb +97 -0
  47. data/test/test_client_expire.rb +132 -0
  48. data/test/test_config.rb +56 -0
  49. data/test/test_fdmap.rb +19 -0
  50. data/test/test_output_buffering.rb +291 -0
  51. data/test/test_queue.rb +59 -0
  52. data/test/test_rack.rb +28 -0
  53. data/test/test_serve_static.rb +42 -0
  54. data/test/test_server.rb +415 -0
  55. data/test/test_stream_file.rb +30 -0
  56. data/test/test_wbuf.rb +136 -0
  57. data/yahns.gemspec +19 -0
  58. metadata +165 -0
@@ -0,0 +1,30 @@
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_relative 'helper'
4
+ require 'timeout'
5
+
6
+ class TestStreamFile < Testcase
7
+ parallelize_me!
8
+ DevFD = Struct.new(:to_path)
9
+
10
+ def test_stream_file
11
+ fp = File.open("COPYING")
12
+ sf = Yahns::StreamFile.new(fp, true, 0, fp.stat.size)
13
+ refute sf.respond_to?(:close)
14
+ sf.wbuf_close(nil)
15
+ assert fp.closed?
16
+ end
17
+
18
+ def test_fd
19
+ fp = File.open("COPYING")
20
+ obj = DevFD.new("/dev/fd/#{fp.fileno}")
21
+ sf = Yahns::StreamFile.new(obj, true, 0, fp.stat.size)
22
+ io = sf.instance_variable_get :@tmpio
23
+ assert_instance_of IO, io.to_io
24
+ assert_equal fp.fileno, io.fileno
25
+ refute sf.respond_to?(:close)
26
+ sf.wbuf_close(nil)
27
+ refute fp.closed?
28
+ refute io.closed?
29
+ end
30
+ end
@@ -0,0 +1,136 @@
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_relative 'helper'
4
+ require 'timeout'
5
+
6
+ class TestWbuf < Testcase
7
+ parallelize_me!
8
+
9
+ def test_wbuf
10
+ buf = "*" * (16384 * 2)
11
+ nr = 1000
12
+ [ true, false ].each do |persist|
13
+ wbuf = Yahns::Wbuf.new([], persist)
14
+ a, b = UNIXSocket.pair
15
+ assert_nil wbuf.wbuf_write(a, "HIHI")
16
+ assert_equal "HIHI", b.read(4)
17
+ nr.times { wbuf.wbuf_write(a, buf) }
18
+ assert_equal :wait_writable, wbuf.wbuf_flush(a)
19
+ done = IO.pipe
20
+ thr = Thread.new do
21
+ rv = []
22
+ until rv[-1] == persist
23
+ IO.select(nil, [a])
24
+ tmp = wbuf.wbuf_flush(a)
25
+ rv << tmp
26
+ end
27
+ done[1].syswrite '.'
28
+ rv
29
+ end
30
+
31
+ wait = true
32
+ begin
33
+ if wait
34
+ r = IO.select([b,done[0]], nil, nil, 5)
35
+ end
36
+ b.read_nonblock((rand * 1024) + 666, buf)
37
+ wait = (r[0] & done).empty?
38
+ rescue Errno::EAGAIN
39
+ break
40
+ end while true
41
+
42
+ assert_equal thr, thr.join(5)
43
+ rv = thr.value
44
+ assert_equal persist, rv.pop
45
+ assert(rv.all? { |x| x == :wait_writable })
46
+ a.close
47
+ b.close
48
+ done.each { |io| io.close }
49
+ end
50
+ end
51
+
52
+ def test_wbuf_blocked
53
+ a, b = UNIXSocket.pair
54
+ buf = "." * 4096
55
+ 4.times do
56
+ begin
57
+ a.write_nonblock(buf)
58
+ rescue Errno::EAGAIN
59
+ break
60
+ end while true
61
+ end
62
+ wbuf = Yahns::Wbuf.new([], true)
63
+ assert_equal :wait_writable, wbuf.wbuf_write(a, buf)
64
+ assert_equal :wait_writable, wbuf.wbuf_flush(a)
65
+
66
+ # drain the buffer
67
+ Timeout.timeout(10) { b.read(b.nread) until b.nread == 0 }
68
+
69
+ # b.nread will increase after this
70
+ assert_nil wbuf.wbuf_write(a, "HI")
71
+ nr = b.nread
72
+ assert_operator nr, :>, 0
73
+ assert_equal b, IO.select([b], nil, nil, 5)[0][0]
74
+ b.read(nr - 2) if nr > 2
75
+ assert_equal b, IO.select([b], nil, nil, 5)[0][0]
76
+ assert_equal "HI", b.read(2)
77
+ begin
78
+ wbuf.wbuf_flush(a)
79
+ assert false
80
+ rescue => e
81
+ end
82
+ assert_match(%r{BUG: EOF on tmpio}, e.message)
83
+ ensure
84
+ a.close
85
+ b.close
86
+ end
87
+
88
+ def test_wbuf_flush_close
89
+ pipe = IO.pipe
90
+ persist = true
91
+ wbuf = Yahns::Wbuf.new(pipe[0], persist)
92
+ refute wbuf.respond_to?(:close) # we don't want this for HttpResponse body
93
+ sp = UNIXSocket.pair
94
+ rv = nil
95
+
96
+ buf = ("*" * 16384) << "\n"
97
+ thr = Thread.new do
98
+ 1000.times { pipe[1].write(buf) }
99
+ pipe[1].close
100
+ end
101
+
102
+ pipe[0].each { |chunk| rv = wbuf.wbuf_write(sp[1], chunk) }
103
+ assert_equal thr, thr.join(5)
104
+ assert_equal :wait_writable, rv
105
+
106
+ done = IO.pipe
107
+ thr = Thread.new do
108
+ rv = []
109
+ until rv[-1] == persist
110
+ IO.select(nil, [sp[1]])
111
+ rv << wbuf.wbuf_flush(sp[1])
112
+ end
113
+ done[1].syswrite '.'
114
+ rv
115
+ end
116
+
117
+ wait = true
118
+ begin
119
+ if wait
120
+ r = IO.select([sp[0],done[0]], nil, nil, 5)
121
+ end
122
+ sp[0].read_nonblock(16384, buf)
123
+ wait = (r[0] & done).empty?
124
+ rescue Errno::EAGAIN
125
+ break
126
+ end while true
127
+
128
+ assert_equal thr, thr.join(5)
129
+ rv = thr.value
130
+ assert_equal true, rv.pop
131
+ assert rv.all? { |x| x == :wait_writable }
132
+ assert pipe[0].closed?
133
+ sp.each(&:close)
134
+ done.each(&:close)
135
+ end
136
+ end
@@ -0,0 +1,19 @@
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
+ Gem::Specification.new do |s|
4
+ manifest = File.read('.gem-manifest').split(/\n/)
5
+ s.name = %q{yahns}
6
+ s.version = ENV["VERSION"]
7
+ s.authors = ["#{name} hackers"]
8
+ s.summary = "sleepy, multi-threaded, non-blocking application server"
9
+ s.description = File.read("README").split(/\n\n/)[1].strip
10
+ s.email = %q{yahns@yhbt.net}
11
+ s.executables = manifest.grep(%r{\Abin/}).map { |s| s.sub(%r{\Abin/}, "") }
12
+ s.files = manifest
13
+ s.add_dependency(%q<kgio>, '~> 2.8')
14
+ s.add_dependency(%q<sleepy_penguin>, '~> 3.2')
15
+ s.add_dependency(%q<sendfile>, '~> 1.2.1')
16
+ s.add_dependency(%q<unicorn>, '~> 4.6.3')
17
+ s.homepage = "http://yahns.yhbt.net/README"
18
+ s.licenses = "GPLv3+"
19
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yahns
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0TP1
5
+ platform: ruby
6
+ authors:
7
+ - Gem::Specification hackers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kgio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sleepy_penguin
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sendfile
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.2.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.2.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: unicorn
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 4.6.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 4.6.3
69
+ description: |-
70
+ A Free Software, multi-threaded, non-blocking network application server
71
+ designed for low _idle_ power consumption. It is primarily optimized
72
+ for applications with occasional users which see little or no traffic.
73
+ yahns currently hosts Rack/HTTP applications, but may eventually support
74
+ other application types. Unlike some existing servers, yahns is
75
+ extremely sensitive to fatal bugs in the applications it hosts.
76
+ email: yahns@yhbt.net
77
+ executables:
78
+ - yahns
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - .gitignore
83
+ - COPYING
84
+ - GIT-VERSION-FILE
85
+ - GIT-VERSION-GEN
86
+ - GNUmakefile
87
+ - NEWS
88
+ - README
89
+ - Rakefile
90
+ - bin/yahns
91
+ - examples/README
92
+ - examples/init.sh
93
+ - examples/logger_mp_safe.rb
94
+ - examples/logrotate.conf
95
+ - examples/yahns_multi.conf.rb
96
+ - examples/yahns_rack_basic.conf.rb
97
+ - lib/yahns.rb
98
+ - lib/yahns/acceptor.rb
99
+ - lib/yahns/client_expire.rb
100
+ - lib/yahns/client_expire_portable.rb
101
+ - lib/yahns/config.rb
102
+ - lib/yahns/daemon.rb
103
+ - lib/yahns/fdmap.rb
104
+ - lib/yahns/http_client.rb
105
+ - lib/yahns/http_context.rb
106
+ - lib/yahns/http_response.rb
107
+ - lib/yahns/log.rb
108
+ - lib/yahns/queue.rb
109
+ - lib/yahns/queue_egg.rb
110
+ - lib/yahns/queue_epoll.rb
111
+ - lib/yahns/rack.rb
112
+ - lib/yahns/server.rb
113
+ - lib/yahns/server_mp.rb
114
+ - lib/yahns/sigevent.rb
115
+ - lib/yahns/sigevent_efd.rb
116
+ - lib/yahns/sigevent_pipe.rb
117
+ - lib/yahns/socket_helper.rb
118
+ - lib/yahns/stream_file.rb
119
+ - lib/yahns/stream_input.rb
120
+ - lib/yahns/tee_input.rb
121
+ - lib/yahns/tmpio.rb
122
+ - lib/yahns/version.rb
123
+ - lib/yahns/wbuf.rb
124
+ - lib/yahns/wbuf_common.rb
125
+ - lib/yahns/worker.rb
126
+ - test/covshow.rb
127
+ - test/helper.rb
128
+ - test/server_helper.rb
129
+ - test/test_bin.rb
130
+ - test/test_client_expire.rb
131
+ - test/test_config.rb
132
+ - test/test_fdmap.rb
133
+ - test/test_output_buffering.rb
134
+ - test/test_queue.rb
135
+ - test/test_rack.rb
136
+ - test/test_serve_static.rb
137
+ - test/test_server.rb
138
+ - test/test_stream_file.rb
139
+ - test/test_wbuf.rb
140
+ - yahns.gemspec
141
+ homepage: http://yahns.yhbt.net/README
142
+ licenses:
143
+ - GPLv3+
144
+ metadata: {}
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '>'
157
+ - !ruby/object:Gem::Version
158
+ version: 1.3.1
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 2.1.3
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: sleepy, multi-threaded, non-blocking application server
165
+ test_files: []