raindrops-maintained 0.21.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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.document +7 -0
  3. data/.gitattributes +4 -0
  4. data/.gitignore +16 -0
  5. data/.manifest +62 -0
  6. data/.olddoc.yml +16 -0
  7. data/COPYING +165 -0
  8. data/GIT-VERSION-FILE +1 -0
  9. data/GIT-VERSION-GEN +40 -0
  10. data/GNUmakefile +4 -0
  11. data/LATEST +9 -0
  12. data/LICENSE +16 -0
  13. data/NEWS +384 -0
  14. data/README +101 -0
  15. data/TODO +3 -0
  16. data/archive/.gitignore +3 -0
  17. data/archive/slrnpull.conf +4 -0
  18. data/examples/linux-listener-stats.rb +122 -0
  19. data/examples/middleware.ru +5 -0
  20. data/examples/watcher.ru +4 -0
  21. data/examples/watcher_demo.ru +13 -0
  22. data/examples/yahns.conf.rb +30 -0
  23. data/examples/zbatery.conf.rb +16 -0
  24. data/ext/raindrops/extconf.rb +163 -0
  25. data/ext/raindrops/linux_inet_diag.c +713 -0
  26. data/ext/raindrops/my_fileno.h +16 -0
  27. data/ext/raindrops/raindrops.c +487 -0
  28. data/ext/raindrops/raindrops_atomic.h +23 -0
  29. data/ext/raindrops/tcp_info.c +245 -0
  30. data/lib/raindrops/aggregate/last_data_recv.rb +94 -0
  31. data/lib/raindrops/aggregate/pmq.rb +245 -0
  32. data/lib/raindrops/aggregate.rb +8 -0
  33. data/lib/raindrops/last_data_recv.rb +102 -0
  34. data/lib/raindrops/linux.rb +77 -0
  35. data/lib/raindrops/middleware/proxy.rb +40 -0
  36. data/lib/raindrops/middleware.rb +153 -0
  37. data/lib/raindrops/struct.rb +62 -0
  38. data/lib/raindrops/watcher.rb +428 -0
  39. data/lib/raindrops.rb +72 -0
  40. data/pkg.mk +151 -0
  41. data/raindrops-maintained.gemspec +1 -0
  42. data/raindrops.gemspec +26 -0
  43. data/setup.rb +1586 -0
  44. data/test/ipv6_enabled.rb +9 -0
  45. data/test/rack_unicorn.rb +11 -0
  46. data/test/test_aggregate_pmq.rb +65 -0
  47. data/test/test_inet_diag_socket.rb +16 -0
  48. data/test/test_last_data_recv.rb +57 -0
  49. data/test/test_last_data_recv_unicorn.rb +69 -0
  50. data/test/test_linux.rb +281 -0
  51. data/test/test_linux_all_tcp_listen_stats.rb +66 -0
  52. data/test/test_linux_all_tcp_listen_stats_leak.rb +43 -0
  53. data/test/test_linux_ipv6.rb +166 -0
  54. data/test/test_linux_middleware.rb +64 -0
  55. data/test/test_linux_reuseport_tcp_listen_stats.rb +51 -0
  56. data/test/test_middleware.rb +128 -0
  57. data/test/test_middleware_unicorn.rb +37 -0
  58. data/test/test_middleware_unicorn_ipv6.rb +37 -0
  59. data/test/test_raindrops.rb +207 -0
  60. data/test/test_raindrops_gc.rb +38 -0
  61. data/test/test_struct.rb +54 -0
  62. data/test/test_tcp_info.rb +88 -0
  63. data/test/test_watcher.rb +186 -0
  64. metadata +193 -0
@@ -0,0 +1,38 @@
1
+ # -*- encoding: binary -*-
2
+ require 'test/unit'
3
+ require 'raindrops'
4
+
5
+ class TestRaindropsGc < Test::Unit::TestCase
6
+
7
+ # we may need to create more garbage as GC may be less aggressive
8
+ # about expiring things. This is completely unrealistic code,
9
+ # though...
10
+ def test_gc
11
+ assert_nothing_raised do
12
+ 1000000.times { |i| Raindrops.new(24); [] }
13
+ end
14
+ end
15
+
16
+ def test_gc_postfork
17
+ tmp = Raindrops.new 2
18
+ pid = fork do
19
+ 1000000.times do
20
+ tmp = Raindrops.new 2
21
+ tmp.to_ary
22
+ end
23
+ end
24
+ _, status = Process.waitpid2(pid)
25
+ assert status.success?
26
+ assert_equal [ 0, 0 ], tmp.to_ary
27
+ tmp.incr 1
28
+ assert_equal [ 0, 1 ], tmp.to_ary
29
+ pid = fork do
30
+ tmp.incr 1
31
+ exit([ 0, 2 ] == tmp.to_ary)
32
+ end
33
+ _, status = Process.waitpid2(pid)
34
+ assert status.success?
35
+ assert_equal [ 0, 2 ], tmp.to_ary
36
+ end
37
+ end if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" &&
38
+ ENV["STRESS"].to_i != 0
@@ -0,0 +1,54 @@
1
+ require 'test/unit'
2
+ require 'raindrops'
3
+
4
+ class TestRaindrops < Test::Unit::TestCase
5
+
6
+ def test_struct_new
7
+ @rw = Raindrops::Struct.new(:r, :w)
8
+ assert @rw.kind_of?(Class)
9
+ end
10
+
11
+ TMP = Raindrops::Struct.new(:r, :w)
12
+
13
+ def test_init_basic
14
+ tmp = TMP.new
15
+ assert_equal 0, tmp.r
16
+ assert_equal 1, tmp.incr_r
17
+ assert_equal 1, tmp.r
18
+ assert_equal({ :r => 1, :w => 0 }, tmp.to_hash)
19
+
20
+ assert_equal 1, tmp[0]
21
+ assert_equal 0, tmp[1]
22
+ assert_equal [ :r, :w ], TMP::MEMBERS
23
+ end
24
+
25
+ def test_init
26
+ tmp = TMP.new(5, 6)
27
+ assert_equal({ :r => 5, :w => 6 }, tmp.to_hash)
28
+ end
29
+
30
+ def test_dup
31
+ a = TMP.new(5, 6)
32
+ b = a.dup
33
+ assert_equal({ :r => 5, :w => 6 }, b.to_hash)
34
+ assert_nothing_raised { 4.times { b.decr_r } }
35
+ assert_equal({ :r => 1, :w => 6 }, b.to_hash)
36
+ assert_equal({ :r => 5, :w => 6 }, a.to_hash)
37
+ end
38
+
39
+ class Foo < Raindrops::Struct.new(:a, :b, :c, :d)
40
+ def to_ary
41
+ @raindrops.to_ary
42
+ end
43
+
44
+ def hello
45
+ "world"
46
+ end
47
+ end
48
+
49
+ def test_subclass
50
+ assert_equal [0, 0, 0, 0], Foo.new.to_ary
51
+ assert_equal "world", Foo.new.hello
52
+ end
53
+
54
+ end
@@ -0,0 +1,88 @@
1
+ # -*- encoding: binary -*-
2
+ require 'test/unit'
3
+ require 'tempfile'
4
+ require 'raindrops'
5
+ require 'socket'
6
+ require 'pp'
7
+ $stderr.sync = $stdout.sync = true
8
+ class TestTCP_Info < Test::Unit::TestCase
9
+
10
+ TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
11
+
12
+ # Linux kernel commit 5ee3afba88f5a79d0bff07ddd87af45919259f91
13
+ TCP_INFO_useful_listenq = `uname -r`.strip >= '2.6.24'
14
+
15
+ def test_tcp_server_unacked
16
+ return if RUBY_PLATFORM !~ /linux/ # unacked not implemented on others...
17
+ s = TCPServer.new(TEST_ADDR, 0)
18
+ rv = Raindrops::TCP_Info.new s
19
+ c = TCPSocket.new TEST_ADDR, s.addr[1]
20
+ tmp = Raindrops::TCP_Info.new s
21
+ TCP_INFO_useful_listenq and assert_equal 1, tmp.unacked
22
+
23
+ assert_equal 0, rv.unacked
24
+ a = s.accept
25
+ tmp = Raindrops::TCP_Info.new s
26
+ assert_equal 0, tmp.unacked
27
+ before = tmp.object_id
28
+
29
+ tmp.get!(s)
30
+ assert_equal before, tmp.object_id
31
+
32
+ ensure
33
+ [ c, a, s ].compact.each(&:close)
34
+ end
35
+
36
+ def test_accessors
37
+ s = TCPServer.new TEST_ADDR, 0
38
+ tmp = Raindrops::TCP_Info.new s
39
+ tcp_info_methods = tmp.methods - Object.new.methods
40
+ assert tcp_info_methods.size >= 32
41
+ tcp_info_methods.each do |m|
42
+ next if m.to_sym == :get!
43
+ next if ! tmp.respond_to?(m)
44
+ val = tmp.__send__ m
45
+ assert_kind_of Integer, val
46
+ assert val >= 0
47
+ end
48
+ assert tmp.respond_to?(:state), 'every OS knows about TCP state, right?'
49
+ ensure
50
+ s.close
51
+ end
52
+
53
+ def test_tcp_server_delayed
54
+ delay = 0.010
55
+ delay_ms = (delay * 1000).to_i
56
+ s = TCPServer.new(TEST_ADDR, 0)
57
+ c = TCPSocket.new TEST_ADDR, s.addr[1]
58
+ c.syswrite "."
59
+ sleep(delay * 1.2)
60
+ a = s.accept
61
+ i = Raindrops::TCP_Info.new(a)
62
+ assert i.last_data_recv >= delay_ms, "#{i.last_data_recv} < #{delay_ms}"
63
+ ensure
64
+ c.close if c
65
+ a.close if a
66
+ s.close
67
+ end
68
+
69
+ def test_tcp_server_state_closed
70
+ s = TCPServer.new(TEST_ADDR, 0)
71
+ c = TCPSocket.new(TEST_ADDR, s.addr[1])
72
+ i = Raindrops::TCP_Info.allocate
73
+ a = s.accept
74
+ i.get!(a)
75
+ state = i.state
76
+ if Raindrops.const_defined?(:TCP)
77
+ assert_equal state, Raindrops::TCP[:ESTABLISHED]
78
+ end
79
+ c = c.close
80
+ sleep(0.01) # wait for kernel to update state
81
+ i.get!(a)
82
+ assert_not_equal state, i.state
83
+ ensure
84
+ s.close if s
85
+ c.close if c
86
+ a.close if a
87
+ end
88
+ end if defined? Raindrops::TCP_Info
@@ -0,0 +1,186 @@
1
+ # -*- encoding: binary -*-
2
+ require "test/unit"
3
+ require "raindrops"
4
+ begin
5
+ require 'aggregate'
6
+ require 'rack'
7
+ rescue LoadError => e
8
+ warn "W: #{e} skipping #{__FILE__}"
9
+ end
10
+
11
+ class TestWatcher < Test::Unit::TestCase
12
+ TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
13
+ def check_headers(headers)
14
+ %w(X-Count X-Std-Dev X-Min X-Max X-Mean
15
+ X-Outliers-Low X-Outliers-Low X-Last-Reset).each { |x|
16
+ assert_kind_of String, headers[x], "#{x} missing"
17
+ }
18
+ end
19
+
20
+ def teardown
21
+ @app.shutdown
22
+ @ios.each { |io| io.close unless io.closed? }
23
+ end
24
+
25
+ def setup
26
+ @ios = []
27
+ @srv = TCPServer.new TEST_ADDR, 0
28
+ @ios << @srv
29
+ @port = @srv.addr[1]
30
+ @client = TCPSocket.new TEST_ADDR, @port
31
+ @addr = "#{TEST_ADDR}:#{@port}"
32
+ @ios << @client
33
+ @app = Raindrops::Watcher.new :delay => 0.001
34
+ @req = Rack::MockRequest.new @app
35
+ end
36
+
37
+ def test_index
38
+ resp = @req.get "/"
39
+ assert_equal 200, resp.status.to_i
40
+ t = Time.parse resp.headers["Last-Modified"]
41
+ assert_in_delta Time.now.to_f, t.to_f, 2.0
42
+ end
43
+
44
+ def test_active_txt
45
+ resp = @req.get "/active/#@addr.txt"
46
+ assert_equal 200, resp.status.to_i
47
+ assert_equal "text/plain", resp.headers["Content-Type"]
48
+ check_headers(resp.headers)
49
+ end
50
+
51
+ def test_invalid
52
+ assert_nothing_raised do
53
+ @req.get("/active/666.666.666.666%3A666.txt")
54
+ @req.get("/queued/666.666.666.666%3A666.txt")
55
+ @req.get("/active/666.666.666.666%3A666.html")
56
+ @req.get("/queued/666.666.666.666%3A666.html")
57
+ end
58
+ addr = @app.instance_eval do
59
+ @peak_active.keys + @peak_queued.keys +
60
+ @resets.keys + @active.keys + @queued.keys
61
+ end
62
+ assert addr.grep(/666\.666\.666\.666/).empty?, addr.inspect
63
+ end
64
+
65
+ def test_active_html
66
+ resp = @req.get "/active/#@addr.html"
67
+ assert_equal 200, resp.status.to_i
68
+ assert_equal "text/html", resp.headers["Content-Type"]
69
+ check_headers(resp.headers)
70
+ end
71
+
72
+ def test_queued_txt
73
+ resp = @req.get "/queued/#@addr.txt"
74
+ assert_equal 200, resp.status.to_i
75
+ assert_equal "text/plain", resp.headers["Content-Type"]
76
+ check_headers(resp.headers)
77
+ end
78
+
79
+ def test_queued_html
80
+ resp = @req.get "/queued/#@addr.html"
81
+ assert_equal 200, resp.status.to_i
82
+ assert_equal "text/html", resp.headers["Content-Type"]
83
+ check_headers(resp.headers)
84
+ end
85
+
86
+ def test_reset
87
+ resp = @req.post "/reset/#@addr"
88
+ assert_equal 302, resp.status.to_i
89
+ end
90
+
91
+ def test_tail
92
+ env = @req.class.env_for "/tail/#@addr.txt"
93
+ status, headers, body = @app.call env
94
+ assert_equal "text/plain", headers["Content-Type"]
95
+ assert_equal 200, status.to_i
96
+ tmp = []
97
+ body.each do |x|
98
+ assert_kind_of String, x
99
+ tmp << x
100
+ break if tmp.size > 1
101
+ end
102
+ end
103
+
104
+ def test_tail_queued_min
105
+ env = @req.class.env_for "/tail/#@addr.txt?queued_min=1"
106
+ status, headers, body = @app.call env
107
+ assert_equal "text/plain", headers["Content-Type"]
108
+ assert_equal 200, status.to_i
109
+ tmp = []
110
+ body.each do |x|
111
+ tmp = TCPSocket.new TEST_ADDR, @port
112
+ @ios << tmp
113
+ assert_kind_of String, x
114
+ assert_equal 1, x.strip.split(/\s+/).last.to_i
115
+ break
116
+ end
117
+ end
118
+
119
+ def test_x_current_header
120
+ env = @req.class.env_for "/active/#@addr.txt"
121
+ _status, headers, _body = @app.call(env)
122
+ assert_equal "0", headers["X-Current"], headers.inspect
123
+
124
+ env = @req.class.env_for "/queued/#@addr.txt"
125
+ _status, headers, _body = @app.call(env)
126
+ assert_equal "1", headers["X-Current"], headers.inspect
127
+
128
+ @ios << @srv.accept
129
+ sleep 0.1
130
+
131
+ env = @req.class.env_for "/queued/#@addr.txt"
132
+ _status, headers, _body = @app.call(env)
133
+ assert_equal "0", headers["X-Current"], headers.inspect
134
+
135
+ env = @req.class.env_for "/active/#@addr.txt"
136
+ _status, headers, _body = @app.call(env)
137
+ assert_equal "1", headers["X-Current"], headers.inspect
138
+ end
139
+
140
+ def test_peaks
141
+ env = @req.class.env_for "/active/#@addr.txt"
142
+ _status, headers, _body = @app.call(env.dup)
143
+ start = headers["X-First-Peak-At"]
144
+ assert headers["X-First-Peak-At"], headers.inspect
145
+ assert headers["X-Last-Peak-At"], headers.inspect
146
+ assert_nothing_raised { Time.parse(headers["X-First-Peak-At"]) }
147
+ assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
148
+ before = headers["X-Last-Peak-At"]
149
+
150
+ env = @req.class.env_for "/queued/#@addr.txt"
151
+ _status, headers, _body = @app.call(env)
152
+ assert_nothing_raised { Time.parse(headers["X-First-Peak-At"]) }
153
+ assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
154
+ assert_equal before, headers["X-Last-Peak-At"], "should not change"
155
+
156
+ sleep 2
157
+ env = @req.class.env_for "/active/#@addr.txt"
158
+ _status, headers, _body = @app.call(env.dup)
159
+ assert_equal before, headers["X-Last-Peak-At"], headers.inspect
160
+
161
+ @ios << @srv.accept
162
+ begin
163
+ @srv.accept_nonblock
164
+ assert false, "we should not get here"
165
+ rescue => e
166
+ assert_kind_of Errno::EAGAIN, e
167
+ end
168
+ sleep 0.1
169
+ env = @req.class.env_for "/queued/#@addr.txt"
170
+ _status, headers, _body = @app.call(env.dup)
171
+ assert headers["X-Last-Peak-At"], headers.inspect
172
+ assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
173
+ assert before != headers["X-Last-Peak-At"]
174
+
175
+ queued_before = headers["X-Last-Peak-At"]
176
+
177
+ sleep 2
178
+
179
+ env = @req.class.env_for "/queued/#@addr.txt"
180
+ _status, headers, _body = @app.call(env)
181
+ assert_equal "0", headers["X-Current"]
182
+ assert_nothing_raised { Time.parse(headers["X-Last-Peak-At"]) }
183
+ assert_equal queued_before, headers["X-Last-Peak-At"], "should not change"
184
+ assert_equal start, headers["X-First-Peak-At"]
185
+ end
186
+ end if RUBY_PLATFORM =~ /linux/ && defined?(Aggregate) && defined?(Rack)
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: raindrops-maintained
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.21.0
5
+ platform: ruby
6
+ authors:
7
+ - raindrops hackers
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2024-03-19 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: aggregate
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.2'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.2'
26
+ - !ruby/object:Gem::Dependency
27
+ name: test-unit
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: posix_mq
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rack
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '1.2'
61
+ - - "<"
62
+ - !ruby/object:Gem::Version
63
+ version: '4'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '1.2'
71
+ - - "<"
72
+ - !ruby/object:Gem::Version
73
+ version: '4'
74
+ description: |-
75
+ raindrops is a real-time stats toolkit to show statistics for Rack HTTP
76
+ servers. It is designed for preforking servers such as unicorn, but
77
+ should support any Rack HTTP server on platforms supporting POSIX shared
78
+ memory. It may also be used as a generic scoreboard for sharing atomic
79
+ counters across multiple processes.
80
+ email: raindrops-public@yhbt.net
81
+ executables: []
82
+ extensions:
83
+ - ext/raindrops/extconf.rb
84
+ extra_rdoc_files:
85
+ - README
86
+ - LICENSE
87
+ - NEWS
88
+ - ext/raindrops/raindrops.c
89
+ - ext/raindrops/linux_inet_diag.c
90
+ - ext/raindrops/tcp_info.c
91
+ files:
92
+ - ".document"
93
+ - ".gitattributes"
94
+ - ".gitignore"
95
+ - ".manifest"
96
+ - ".olddoc.yml"
97
+ - COPYING
98
+ - GIT-VERSION-FILE
99
+ - GIT-VERSION-GEN
100
+ - GNUmakefile
101
+ - LATEST
102
+ - LICENSE
103
+ - NEWS
104
+ - README
105
+ - TODO
106
+ - archive/.gitignore
107
+ - archive/slrnpull.conf
108
+ - examples/linux-listener-stats.rb
109
+ - examples/middleware.ru
110
+ - examples/watcher.ru
111
+ - examples/watcher_demo.ru
112
+ - examples/yahns.conf.rb
113
+ - examples/zbatery.conf.rb
114
+ - ext/raindrops/extconf.rb
115
+ - ext/raindrops/linux_inet_diag.c
116
+ - ext/raindrops/my_fileno.h
117
+ - ext/raindrops/raindrops.c
118
+ - ext/raindrops/raindrops_atomic.h
119
+ - ext/raindrops/tcp_info.c
120
+ - lib/raindrops.rb
121
+ - lib/raindrops/aggregate.rb
122
+ - lib/raindrops/aggregate/last_data_recv.rb
123
+ - lib/raindrops/aggregate/pmq.rb
124
+ - lib/raindrops/last_data_recv.rb
125
+ - lib/raindrops/linux.rb
126
+ - lib/raindrops/middleware.rb
127
+ - lib/raindrops/middleware/proxy.rb
128
+ - lib/raindrops/struct.rb
129
+ - lib/raindrops/watcher.rb
130
+ - pkg.mk
131
+ - raindrops-maintained.gemspec
132
+ - raindrops.gemspec
133
+ - setup.rb
134
+ - test/ipv6_enabled.rb
135
+ - test/rack_unicorn.rb
136
+ - test/test_aggregate_pmq.rb
137
+ - test/test_inet_diag_socket.rb
138
+ - test/test_last_data_recv.rb
139
+ - test/test_last_data_recv_unicorn.rb
140
+ - test/test_linux.rb
141
+ - test/test_linux_all_tcp_listen_stats.rb
142
+ - test/test_linux_all_tcp_listen_stats_leak.rb
143
+ - test/test_linux_ipv6.rb
144
+ - test/test_linux_middleware.rb
145
+ - test/test_linux_reuseport_tcp_listen_stats.rb
146
+ - test/test_middleware.rb
147
+ - test/test_middleware_unicorn.rb
148
+ - test/test_middleware_unicorn_ipv6.rb
149
+ - test/test_raindrops.rb
150
+ - test/test_raindrops_gc.rb
151
+ - test/test_struct.rb
152
+ - test/test_tcp_info.rb
153
+ - test/test_watcher.rb
154
+ homepage: https://yhbt.net/raindrops/
155
+ licenses:
156
+ - LGPL-2.1+
157
+ metadata: {}
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: 1.9.3
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubygems_version: 3.6.0.dev
173
+ specification_version: 4
174
+ summary: real-time stats for preforking Rack servers
175
+ test_files:
176
+ - test/test_aggregate_pmq.rb
177
+ - test/test_inet_diag_socket.rb
178
+ - test/test_last_data_recv.rb
179
+ - test/test_last_data_recv_unicorn.rb
180
+ - test/test_linux.rb
181
+ - test/test_linux_all_tcp_listen_stats.rb
182
+ - test/test_linux_all_tcp_listen_stats_leak.rb
183
+ - test/test_linux_ipv6.rb
184
+ - test/test_linux_middleware.rb
185
+ - test/test_linux_reuseport_tcp_listen_stats.rb
186
+ - test/test_middleware.rb
187
+ - test/test_middleware_unicorn.rb
188
+ - test/test_middleware_unicorn_ipv6.rb
189
+ - test/test_raindrops.rb
190
+ - test/test_raindrops_gc.rb
191
+ - test/test_struct.rb
192
+ - test/test_tcp_info.rb
193
+ - test/test_watcher.rb