raindrops 0.6.1 → 0.7.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.
- data/GIT-VERSION-GEN +1 -1
- data/Gemfile +0 -1
- data/README +2 -2
- data/examples/linux-listener-stats.rb +1 -1
- data/ext/raindrops/extconf.rb +1 -1
- data/ext/raindrops/linux_inet_diag.c +39 -40
- data/lib/raindrops.rb +1 -1
- data/lib/raindrops/aggregate/last_data_recv.rb +2 -1
- data/lib/raindrops/aggregate/pmq.rb +3 -3
- data/lib/raindrops/last_data_recv.rb +2 -2
- data/lib/raindrops/watcher.rb +10 -9
- data/pkg.mk +5 -1
- data/raindrops.gemspec +1 -1
- data/test/ipv6_enabled.rb +1 -2
- data/test/test_aggregate_pmq.rb +1 -1
- data/test/test_linux.rb +26 -18
- data/test/test_linux_ipv6.rb +10 -10
- data/test/test_linux_middleware.rb +8 -3
- data/test/test_linux_tcp_info.rb +1 -1
- data/test/test_middleware_unicorn.rb +1 -1
- data/test/test_middleware_unicorn_ipv6.rb +1 -1
- metadata +7 -9
data/GIT-VERSION-GEN
CHANGED
data/Gemfile
CHANGED
data/README
CHANGED
@@ -62,7 +62,7 @@ Unpack it, and run "ruby setup.rb"
|
|
62
62
|
|
63
63
|
See Raindrops::Middleware and Raindrops::LastDataRecv documentation for
|
64
64
|
use Rack servers. The entire library is fully-documented and we are
|
65
|
-
responsive on the mailing list (mailto:raindrops@librelist.
|
65
|
+
responsive on the mailing list (mailto:raindrops@librelist.org) if you
|
66
66
|
have any questions or comments.
|
67
67
|
|
68
68
|
== Development
|
@@ -96,7 +96,7 @@ similar in spirit to the existing LGPL).
|
|
96
96
|
== Contact
|
97
97
|
|
98
98
|
All feedback (bug reports, user/development discussion, patches, pull
|
99
|
-
requests) go to the mailing list: mailto:raindrops@librelist.
|
99
|
+
requests) go to the mailing list: mailto:raindrops@librelist.org
|
100
100
|
|
101
101
|
The mailing list is mirrored to Gmane, all information about the
|
102
102
|
group is here:
|
@@ -21,7 +21,7 @@ queued_thresh = -1
|
|
21
21
|
trap(:INT) { exit 130 }
|
22
22
|
trap(:PIPE) { exit 0 }
|
23
23
|
|
24
|
-
|
24
|
+
OptionParser.new('', 24, ' ') do |opts|
|
25
25
|
opts.banner = usage
|
26
26
|
opts.on('-d', '--delay=DELAY', Float) { |n| delay = n }
|
27
27
|
opts.on('-t', '--queued-threshold=INT', Integer) { |n| queued_thresh = n }
|
data/ext/raindrops/extconf.rb
CHANGED
@@ -7,7 +7,7 @@ have_func('munmap', 'sys/mman.h') or abort 'munmap() not found'
|
|
7
7
|
$CPPFLAGS += " -D_GNU_SOURCE "
|
8
8
|
have_func('mremap', 'sys/mman.h')
|
9
9
|
|
10
|
-
$CPPFLAGS += " -D_BSD_SOURCE
|
10
|
+
$CPPFLAGS += " -D_BSD_SOURCE "
|
11
11
|
have_func("getpagesize", "unistd.h")
|
12
12
|
have_func('rb_thread_blocking_region')
|
13
13
|
have_func('rb_thread_io_blocking_region')
|
@@ -54,6 +54,13 @@ rb_thread_blocking_region(
|
|
54
54
|
#include <linux/rtnetlink.h>
|
55
55
|
#include <linux/inet_diag.h>
|
56
56
|
|
57
|
+
union any_addr {
|
58
|
+
struct sockaddr_storage ss;
|
59
|
+
struct sockaddr sa;
|
60
|
+
struct sockaddr_in in;
|
61
|
+
struct sockaddr_in6 in6;
|
62
|
+
};
|
63
|
+
|
57
64
|
static size_t page_size;
|
58
65
|
static unsigned g_seq;
|
59
66
|
static VALUE cListenStats, cIDSock;
|
@@ -169,7 +176,7 @@ static const char *addr_any(sa_family_t family)
|
|
169
176
|
static void bug_warn(void)
|
170
177
|
{
|
171
178
|
fprintf(stderr, "Please report how you produced this at "\
|
172
|
-
"raindrops@librelist.
|
179
|
+
"raindrops@librelist.org\n");
|
173
180
|
fflush(stderr);
|
174
181
|
}
|
175
182
|
|
@@ -180,30 +187,27 @@ static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
|
180
187
|
struct listen_stats *stats;
|
181
188
|
size_t keylen;
|
182
189
|
size_t portlen = sizeof("65535");
|
183
|
-
|
190
|
+
union any_addr sa = { 0 };
|
184
191
|
socklen_t len = sizeof(struct sockaddr_storage);
|
185
192
|
int rc;
|
186
193
|
int flags = NI_NUMERICHOST | NI_NUMERICSERV;
|
187
194
|
|
188
|
-
switch ((ss.ss_family = r->idiag_family)) {
|
195
|
+
switch ((sa.ss.ss_family = r->idiag_family)) {
|
189
196
|
case AF_INET: {
|
190
|
-
|
191
|
-
|
192
|
-
in->sin_port = r->id.idiag_sport;
|
193
|
-
in->sin_addr.s_addr = r->id.idiag_src[0];
|
197
|
+
sa.in.sin_port = r->id.idiag_sport;
|
198
|
+
sa.in.sin_addr.s_addr = r->id.idiag_src[0];
|
194
199
|
keylen = INET_ADDRSTRLEN;
|
195
200
|
alloca_len = keylen + 1 + portlen;
|
196
201
|
key = alloca(alloca_len);
|
197
202
|
key[keylen] = 0; /* will be ':' later */
|
198
203
|
port = key + keylen + 1;
|
199
|
-
rc = getnameinfo(
|
204
|
+
rc = getnameinfo(&sa.sa, len,
|
200
205
|
key, keylen, port, portlen, flags);
|
201
206
|
break;
|
202
207
|
}
|
203
208
|
case AF_INET6: {
|
204
|
-
|
205
|
-
in6
|
206
|
-
memcpy(&in6->sin6_addr, &r->id.idiag_src, sizeof(__be32[4]));
|
209
|
+
sa.in6.sin6_port = r->id.idiag_sport;
|
210
|
+
memcpy(&sa.in6.sin6_addr, &r->id.idiag_src, sizeof(__be32[4]));
|
207
211
|
keylen = INET6_ADDRSTRLEN;
|
208
212
|
/* [ ] */
|
209
213
|
alloca_len = 1 + keylen + 1 + 1 + portlen;
|
@@ -211,7 +215,7 @@ static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
|
211
215
|
*key = '[';
|
212
216
|
key[1 + keylen + 1] = 0; /* will be ':' later */
|
213
217
|
port = 1 + key + keylen + 1 + 1;
|
214
|
-
rc = getnameinfo(
|
218
|
+
rc = getnameinfo(&sa.sa, len,
|
215
219
|
key + 1, keylen, port, portlen, flags);
|
216
220
|
break;
|
217
221
|
}
|
@@ -227,7 +231,7 @@ static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
|
227
231
|
keylen = strlen(key);
|
228
232
|
portlen = strlen(port);
|
229
233
|
|
230
|
-
switch (ss.ss_family) {
|
234
|
+
switch (sa.ss.ss_family) {
|
231
235
|
case AF_INET:
|
232
236
|
key[keylen] = ':';
|
233
237
|
memmove(key + keylen + 1, port, portlen + 1);
|
@@ -249,7 +253,7 @@ static struct listen_stats *stats_for(st_table *table, struct inet_diag_msg *r)
|
|
249
253
|
|
250
254
|
if (r->idiag_state == TCP_ESTABLISHED) {
|
251
255
|
int n = snprintf(key, alloca_len, "%s:%u",
|
252
|
-
addr_any(ss.ss_family),
|
256
|
+
addr_any(sa.ss.ss_family),
|
253
257
|
ntohs(r->id.idiag_sport));
|
254
258
|
if (n <= 0) {
|
255
259
|
fprintf(stderr, "BUG: snprintf: %d\n", n);
|
@@ -433,7 +437,7 @@ out:
|
|
433
437
|
}
|
434
438
|
|
435
439
|
/* populates sockaddr_storage struct by parsing +addr+ */
|
436
|
-
static void parse_addr(
|
440
|
+
static void parse_addr(union any_addr *inet, VALUE addr)
|
437
441
|
{
|
438
442
|
char *host_ptr;
|
439
443
|
char *check;
|
@@ -449,7 +453,6 @@ static void parse_addr(struct sockaddr_storage *inet, VALUE addr)
|
|
449
453
|
host_ptr = StringValueCStr(addr);
|
450
454
|
host_len = RSTRING_LEN(addr);
|
451
455
|
if (*host_ptr == '[') { /* ipv6 address format (rfc2732) */
|
452
|
-
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)inet;
|
453
456
|
rbracket = memchr(host_ptr + 1, ']', host_len - 1);
|
454
457
|
|
455
458
|
if (rbracket == NULL)
|
@@ -461,15 +464,14 @@ static void parse_addr(struct sockaddr_storage *inet, VALUE addr)
|
|
461
464
|
colon = rbracket + 1;
|
462
465
|
host_ptr++;
|
463
466
|
*rbracket = 0;
|
464
|
-
inet->ss_family = af = AF_INET6;
|
465
|
-
dst = &in6
|
466
|
-
portdst = &in6
|
467
|
+
inet->ss.ss_family = af = AF_INET6;
|
468
|
+
dst = &inet->in6.sin6_addr;
|
469
|
+
portdst = &inet->in6.sin6_port;
|
467
470
|
} else { /* ipv4 */
|
468
|
-
struct sockaddr_in *in = (struct sockaddr_in *)inet;
|
469
471
|
colon = memchr(host_ptr, ':', host_len);
|
470
|
-
inet->ss_family = af = AF_INET;
|
471
|
-
dst = &in
|
472
|
-
portdst = &in
|
472
|
+
inet->ss.ss_family = af = AF_INET;
|
473
|
+
dst = &inet->in.sin_addr;
|
474
|
+
portdst = &inet->in.sin_port;
|
473
475
|
}
|
474
476
|
|
475
477
|
if (!colon)
|
@@ -506,7 +508,7 @@ static void gen_bytecode_all(struct iovec *iov)
|
|
506
508
|
}
|
507
509
|
|
508
510
|
/* generates inet_diag bytecode to match a single addr */
|
509
|
-
static void gen_bytecode(struct iovec *iov,
|
511
|
+
static void gen_bytecode(struct iovec *iov, union any_addr *inet)
|
510
512
|
{
|
511
513
|
struct inet_diag_bc_op *op;
|
512
514
|
struct inet_diag_hostcond *cond;
|
@@ -519,25 +521,22 @@ static void gen_bytecode(struct iovec *iov, struct sockaddr_storage *inet)
|
|
519
521
|
op->no = sizeof(struct inet_diag_bc_op) + OPLEN;
|
520
522
|
|
521
523
|
cond = (struct inet_diag_hostcond *)(op + 1);
|
522
|
-
cond->family = inet->ss_family;
|
523
|
-
switch (inet->ss_family) {
|
524
|
+
cond->family = inet->ss.ss_family;
|
525
|
+
switch (inet->ss.ss_family) {
|
524
526
|
case AF_INET: {
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
cond->
|
529
|
-
sizeof(in->sin_addr.s_addr) * CHAR_BIT;
|
530
|
-
*cond->addr = in->sin_addr.s_addr;
|
527
|
+
cond->port = ntohs(inet->in.sin_port);
|
528
|
+
cond->prefix_len = inet->in.sin_addr.s_addr == 0 ? 0 :
|
529
|
+
sizeof(inet->in.sin_addr.s_addr) * CHAR_BIT;
|
530
|
+
*cond->addr = inet->in.sin_addr.s_addr;
|
531
531
|
}
|
532
532
|
break;
|
533
533
|
case AF_INET6: {
|
534
|
-
|
535
|
-
|
536
|
-
cond->port = ntohs(in6->sin6_port);
|
537
|
-
cond->prefix_len = memcmp(&in6addr_any, &in6->sin6_addr,
|
534
|
+
cond->port = ntohs(inet->in6.sin6_port);
|
535
|
+
cond->prefix_len = memcmp(&in6addr_any, &inet->in6.sin6_addr,
|
538
536
|
sizeof(struct in6_addr)) == 0 ?
|
539
|
-
0 : sizeof(in6
|
540
|
-
memcpy(&cond->addr, &in6
|
537
|
+
0 : sizeof(inet->in6.sin6_addr) * CHAR_BIT;
|
538
|
+
memcpy(&cond->addr, &inet->in6.sin6_addr,
|
539
|
+
sizeof(struct in6_addr));
|
541
540
|
}
|
542
541
|
break;
|
543
542
|
default:
|
@@ -559,7 +558,7 @@ static void nl_errcheck(VALUE r)
|
|
559
558
|
|
560
559
|
static VALUE tcp_stats(struct nogvl_args *args, VALUE addr)
|
561
560
|
{
|
562
|
-
|
561
|
+
union any_addr query_addr;
|
563
562
|
|
564
563
|
parse_addr(&query_addr, addr);
|
565
564
|
gen_bytecode(&args->iov[2], &query_addr);
|
@@ -617,7 +616,7 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self)
|
|
617
616
|
return rv;
|
618
617
|
}
|
619
618
|
for (; --i >= 0; ary++) {
|
620
|
-
|
619
|
+
union any_addr check;
|
621
620
|
|
622
621
|
parse_addr(&check, *ary);
|
623
622
|
rb_hash_aset(rv, *ary, Qtrue);
|
data/lib/raindrops.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
# Unlike many classes in this package, the core Raindrops class is
|
13
13
|
# intended to be portable to all reasonably modern *nix systems
|
14
14
|
# supporting mmap(). Please let us know if you have portability
|
15
|
-
# issues, patches or pull requests at mailto:raindrops@librelist.
|
15
|
+
# issues, patches or pull requests at mailto:raindrops@librelist.org
|
16
16
|
class Raindrops
|
17
17
|
|
18
18
|
# Used to represent the number of +active+ and +queued+ sockets for
|
@@ -46,7 +46,8 @@ module Raindrops::Aggregate::LastDataRecv
|
|
46
46
|
# for accuracy.
|
47
47
|
def self.extended(obj)
|
48
48
|
obj.raindrops_aggregate = default_aggregate
|
49
|
-
obj.setsockopt Socket::SOL_TCP, tcp_defer_accept = 9, seconds = 60
|
49
|
+
# obj.setsockopt Socket::SOL_TCP, tcp_defer_accept = 9, seconds = 60
|
50
|
+
obj.setsockopt Socket::SOL_TCP, 9, 60
|
50
51
|
end
|
51
52
|
|
52
53
|
# :stopdoc:
|
@@ -229,11 +229,11 @@ class Raindrops::Aggregate::PMQ
|
|
229
229
|
def outliers_high; aggregate.outliers_high; end
|
230
230
|
|
231
231
|
# proxy for \Aggregate#to_s
|
232
|
-
def to_s(*args); aggregate.to_s
|
232
|
+
def to_s(*args); aggregate.to_s(*args); end
|
233
233
|
|
234
234
|
# proxy for \Aggregate#each
|
235
|
-
def each; aggregate.each { |*args| yield
|
235
|
+
def each; aggregate.each { |*args| yield(*args) }; end
|
236
236
|
|
237
237
|
# proxy for \Aggregate#each_nonzero
|
238
|
-
def each_nonzero; aggregate.each_nonzero { |*args| yield
|
238
|
+
def each_nonzero; aggregate.each_nonzero { |*args| yield(*args) }; end
|
239
239
|
end
|
@@ -4,8 +4,8 @@ require "raindrops"
|
|
4
4
|
# This is highly experimental!
|
5
5
|
#
|
6
6
|
# A self-contained Rack application for aggregating in the
|
7
|
-
# +tcpi_last_data_recv+ field in +struct tcp_info+
|
8
|
-
#
|
7
|
+
# +tcpi_last_data_recv+ field in +struct+ +tcp_info+ defined in
|
8
|
+
# +/usr/include/linux/tcp.h+. This is only useful for \Linux 2.6 and later.
|
9
9
|
# This primarily supports Unicorn and derived servers, but may also be
|
10
10
|
# used with any Ruby web server using the core TCPServer class in Ruby.
|
11
11
|
#
|
data/lib/raindrops/watcher.rb
CHANGED
@@ -72,19 +72,19 @@ require "aggregate"
|
|
72
72
|
# - active_min - do not stream a line until this active count is reached
|
73
73
|
# - queued_min - do not stream a line until this queued count is reached
|
74
74
|
#
|
75
|
-
# == Response headers (mostly the same as Raindrops::LastDataRecv)
|
75
|
+
# == Response headers (mostly the same names as Raindrops::LastDataRecv)
|
76
76
|
#
|
77
|
-
# - X-Count - number of
|
77
|
+
# - X-Count - number of samples polled
|
78
78
|
# - X-Last-Reset - date since the last reset
|
79
79
|
#
|
80
80
|
# The following headers are only present if X-Count is greater than one.
|
81
81
|
#
|
82
|
-
# - X-Min - lowest
|
83
|
-
# - X-Max - highest
|
84
|
-
# - X-Mean - mean
|
85
|
-
# - X-Std-Dev - standard deviation of
|
86
|
-
# - X-Outliers-Low - number of low outliers (hopefully many
|
87
|
-
# - X-Outliers-High - number of high outliers (hopefully zero
|
82
|
+
# - X-Min - lowest number of connections recorded
|
83
|
+
# - X-Max - highest number of connections recorded
|
84
|
+
# - X-Mean - mean number of connections recorded
|
85
|
+
# - X-Std-Dev - standard deviation of connection count
|
86
|
+
# - X-Outliers-Low - number of low outliers (hopefully many for queued)
|
87
|
+
# - X-Outliers-High - number of high outliers (hopefully zero for queued)
|
88
88
|
#
|
89
89
|
# = Demo Server
|
90
90
|
#
|
@@ -228,6 +228,7 @@ class Raindrops::Watcher
|
|
228
228
|
end
|
229
229
|
|
230
230
|
def get(env)
|
231
|
+
retried = false
|
231
232
|
case env["PATH_INFO"]
|
232
233
|
when "/"
|
233
234
|
index
|
@@ -247,7 +248,7 @@ class Raindrops::Watcher
|
|
247
248
|
not_found
|
248
249
|
end
|
249
250
|
rescue Errno::EDOM
|
250
|
-
raise if
|
251
|
+
raise if retried
|
251
252
|
retried = true
|
252
253
|
wait_snapshot
|
253
254
|
retry
|
data/pkg.mk
CHANGED
@@ -69,7 +69,7 @@ doc:: .document .wrongdoc.yml $(pkg_extra)
|
|
69
69
|
$(RM) -r doc
|
70
70
|
$(WRONGDOC) all
|
71
71
|
install -m644 COPYING doc/COPYING
|
72
|
-
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
72
|
+
install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
|
73
73
|
|
74
74
|
ifneq ($(VERSION),)
|
75
75
|
pkggem := pkg/$(rfpackage)-$(VERSION).gem
|
@@ -167,5 +167,9 @@ doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
|
|
167
167
|
doc_gz:
|
168
168
|
for i in $(docs); do \
|
169
169
|
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
170
|
+
check-warnings:
|
171
|
+
@(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
|
172
|
+
do $(RUBY) -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
|
170
173
|
|
171
174
|
.PHONY: all .FORCE-GIT-VERSION-FILE doc test $(test_units) manifest
|
175
|
+
.PHONY: check-warnings
|
data/raindrops.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.authors = ["raindrops hackers"]
|
14
14
|
s.date = Time.now.utc.strftime('%Y-%m-%d')
|
15
15
|
s.description = readme_description
|
16
|
-
s.email = %q{raindrops@librelist.
|
16
|
+
s.email = %q{raindrops@librelist.org}
|
17
17
|
s.extensions = %w(ext/raindrops/extconf.rb)
|
18
18
|
s.extra_rdoc_files = extra_rdoc_files(manifest)
|
19
19
|
s.files = manifest
|
data/test/ipv6_enabled.rb
CHANGED
data/test/test_aggregate_pmq.rb
CHANGED
@@ -49,7 +49,7 @@ class TestAggregatePMQ < Test::Unit::TestCase
|
|
49
49
|
pmq.flush
|
50
50
|
}
|
51
51
|
}
|
52
|
-
workers.each { |
|
52
|
+
workers.each { |wpid| assert Process.waitpid2(wpid).last.success? }
|
53
53
|
pmq.stop_master_loop
|
54
54
|
assert Process.waitpid2(pid).last.success?
|
55
55
|
assert_equal 400, pmq.count
|
data/test/test_linux.rb
CHANGED
@@ -11,6 +11,14 @@ class TestLinux < Test::Unit::TestCase
|
|
11
11
|
|
12
12
|
TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
|
13
13
|
|
14
|
+
def setup
|
15
|
+
@to_close = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@to_close.each { |io| io.close unless io.closed? }
|
20
|
+
end
|
21
|
+
|
14
22
|
def test_unix
|
15
23
|
tmp = Tempfile.new("\xde\xad\xbe\xef") # valid path, really :)
|
16
24
|
File.unlink(tmp.path)
|
@@ -20,19 +28,19 @@ class TestLinux < Test::Unit::TestCase
|
|
20
28
|
assert_equal 0, stats[tmp.path].active
|
21
29
|
assert_equal 0, stats[tmp.path].queued
|
22
30
|
|
23
|
-
|
31
|
+
@to_close << UNIXSocket.new(tmp.path)
|
24
32
|
stats = unix_listener_stats([tmp.path])
|
25
33
|
assert_equal 1, stats.size
|
26
34
|
assert_equal 0, stats[tmp.path].active
|
27
35
|
assert_equal 1, stats[tmp.path].queued
|
28
36
|
|
29
|
-
|
37
|
+
@to_close << UNIXSocket.new(tmp.path)
|
30
38
|
stats = unix_listener_stats([tmp.path])
|
31
39
|
assert_equal 1, stats.size
|
32
40
|
assert_equal 0, stats[tmp.path].active
|
33
41
|
assert_equal 2, stats[tmp.path].queued
|
34
42
|
|
35
|
-
|
43
|
+
@to_close << us.accept
|
36
44
|
stats = unix_listener_stats([tmp.path])
|
37
45
|
assert_equal 1, stats.size
|
38
46
|
assert_equal 1, stats[tmp.path].active
|
@@ -43,17 +51,17 @@ class TestLinux < Test::Unit::TestCase
|
|
43
51
|
tmp = Tempfile.new("\xde\xad\xbe\xef") # valid path, really :)
|
44
52
|
File.unlink(tmp.path)
|
45
53
|
us = UNIXServer.new(tmp.path)
|
46
|
-
|
54
|
+
@to_close << UNIXSocket.new(tmp.path)
|
47
55
|
stats = unix_listener_stats
|
48
56
|
assert_equal 0, stats[tmp.path].active
|
49
57
|
assert_equal 1, stats[tmp.path].queued
|
50
58
|
|
51
|
-
|
59
|
+
@to_close << UNIXSocket.new(tmp.path)
|
52
60
|
stats = unix_listener_stats
|
53
61
|
assert_equal 0, stats[tmp.path].active
|
54
62
|
assert_equal 2, stats[tmp.path].queued
|
55
63
|
|
56
|
-
|
64
|
+
@to_close << us.accept
|
57
65
|
stats = unix_listener_stats
|
58
66
|
assert_equal 1, stats[tmp.path].active
|
59
67
|
assert_equal 1, stats[tmp.path].queued
|
@@ -69,13 +77,13 @@ class TestLinux < Test::Unit::TestCase
|
|
69
77
|
assert_equal 0, stats[addr].queued
|
70
78
|
assert_equal 0, stats[addr].active
|
71
79
|
|
72
|
-
|
80
|
+
@to_close << TCPSocket.new(TEST_ADDR, port)
|
73
81
|
stats = tcp_listener_stats(addrs)
|
74
82
|
assert_equal 1, stats.size
|
75
83
|
assert_equal 1, stats[addr].queued
|
76
84
|
assert_equal 0, stats[addr].active
|
77
85
|
|
78
|
-
|
86
|
+
@to_close << s.accept
|
79
87
|
stats = tcp_listener_stats(addrs)
|
80
88
|
assert_equal 1, stats.size
|
81
89
|
assert_equal 0, stats[addr].queued
|
@@ -93,13 +101,13 @@ class TestLinux < Test::Unit::TestCase
|
|
93
101
|
assert_equal 0, stats[addr].queued
|
94
102
|
assert_equal 0, stats[addr].active
|
95
103
|
|
96
|
-
|
104
|
+
@to_close << TCPSocket.new(TEST_ADDR, port)
|
97
105
|
stats = tcp_listener_stats(addrs, nlsock)
|
98
106
|
assert_equal 1, stats.size
|
99
107
|
assert_equal 1, stats[addr].queued
|
100
108
|
assert_equal 0, stats[addr].active
|
101
109
|
|
102
|
-
|
110
|
+
@to_close << s.accept
|
103
111
|
stats = tcp_listener_stats(addrs, nlsock)
|
104
112
|
assert_equal 1, stats.size
|
105
113
|
assert_equal 0, stats[addr].queued
|
@@ -121,7 +129,7 @@ class TestLinux < Test::Unit::TestCase
|
|
121
129
|
assert_equal 0, stats[addr2].queued
|
122
130
|
assert_equal 0, stats[addr2].active
|
123
131
|
|
124
|
-
|
132
|
+
@to_close << TCPSocket.new(TEST_ADDR, port1)
|
125
133
|
stats = tcp_listener_stats(addrs)
|
126
134
|
assert_equal 2, stats.size
|
127
135
|
assert_equal 1, stats[addr1].queued
|
@@ -137,7 +145,7 @@ class TestLinux < Test::Unit::TestCase
|
|
137
145
|
assert_equal 0, stats[addr2].queued
|
138
146
|
assert_equal 0, stats[addr2].active
|
139
147
|
|
140
|
-
|
148
|
+
@to_close << TCPSocket.new(TEST_ADDR, port2)
|
141
149
|
stats = tcp_listener_stats(addrs)
|
142
150
|
assert_equal 2, stats.size
|
143
151
|
assert_equal 0, stats[addr1].queued
|
@@ -145,7 +153,7 @@ class TestLinux < Test::Unit::TestCase
|
|
145
153
|
assert_equal 1, stats[addr2].queued
|
146
154
|
assert_equal 0, stats[addr2].active
|
147
155
|
|
148
|
-
|
156
|
+
@to_close << TCPSocket.new(TEST_ADDR, port2)
|
149
157
|
stats = tcp_listener_stats(addrs)
|
150
158
|
assert_equal 2, stats.size
|
151
159
|
assert_equal 0, stats[addr1].queued
|
@@ -153,7 +161,7 @@ class TestLinux < Test::Unit::TestCase
|
|
153
161
|
assert_equal 2, stats[addr2].queued
|
154
162
|
assert_equal 0, stats[addr2].active
|
155
163
|
|
156
|
-
|
164
|
+
@to_close << s2.accept
|
157
165
|
stats = tcp_listener_stats(addrs)
|
158
166
|
assert_equal 2, stats.size
|
159
167
|
assert_equal 0, stats[addr1].queued
|
@@ -184,7 +192,7 @@ class TestLinux < Test::Unit::TestCase
|
|
184
192
|
fork do
|
185
193
|
rda.close
|
186
194
|
wrb.close
|
187
|
-
|
195
|
+
@to_close.concat((1..nr_sock).map { s.accept })
|
188
196
|
wra.syswrite('.')
|
189
197
|
wra.close
|
190
198
|
rdb.sysread(1) # wait for parent to nuke us
|
@@ -195,7 +203,7 @@ class TestLinux < Test::Unit::TestCase
|
|
195
203
|
fork do
|
196
204
|
rda.close
|
197
205
|
wrb.close
|
198
|
-
|
206
|
+
@to_close.concat((1..nr_sock).map { TCPSocket.new(TEST_ADDR, port) })
|
199
207
|
wra.syswrite('.')
|
200
208
|
wra.close
|
201
209
|
rdb.sysread(1) # wait for parent to nuke us
|
@@ -209,7 +217,7 @@ class TestLinux < Test::Unit::TestCase
|
|
209
217
|
expect = { addr => Raindrops::ListenStats[nr_sock * nr_proc, 0] }
|
210
218
|
assert_equal expect, stats
|
211
219
|
|
212
|
-
|
220
|
+
@to_close << TCPSocket.new(TEST_ADDR, port)
|
213
221
|
stats = tcp_listener_stats(addrs)
|
214
222
|
expect = { addr => Raindrops::ListenStats[nr_sock * nr_proc, 1] }
|
215
223
|
assert_equal expect, stats
|
@@ -221,6 +229,6 @@ class TestLinux < Test::Unit::TestCase
|
|
221
229
|
|
222
230
|
wrb.syswrite('.' * (nr_proc * 2)) # broadcast a wakeup
|
223
231
|
statuses = Process.waitall
|
224
|
-
statuses.each { |(
|
232
|
+
statuses.each { |(_,status)| assert status.success?, status.inspect }
|
225
233
|
end if ENV["STRESS"].to_i != 0
|
226
234
|
end if RUBY_PLATFORM =~ /linux/
|
data/test/test_linux_ipv6.rb
CHANGED
@@ -22,13 +22,13 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
22
22
|
assert_equal 0, stats[addr].queued
|
23
23
|
assert_equal 0, stats[addr].active
|
24
24
|
|
25
|
-
|
25
|
+
@to_close << TCPSocket.new(TEST_ADDR, port)
|
26
26
|
stats = tcp_listener_stats(addrs)
|
27
27
|
assert_equal 1, stats.size
|
28
28
|
assert_equal 1, stats[addr].queued
|
29
29
|
assert_equal 0, stats[addr].active
|
30
30
|
|
31
|
-
|
31
|
+
@to_close << s.accept
|
32
32
|
stats = tcp_listener_stats(addrs)
|
33
33
|
assert_equal 1, stats.size
|
34
34
|
assert_equal 0, stats[addr].queued
|
@@ -48,7 +48,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
48
48
|
assert_equal 0, stats[addr2].queued
|
49
49
|
assert_equal 0, stats[addr2].active
|
50
50
|
|
51
|
-
|
51
|
+
@to_close << TCPSocket.new(TEST_ADDR, port1)
|
52
52
|
stats = tcp_listener_stats(addrs)
|
53
53
|
assert_equal 2, stats.size
|
54
54
|
assert_equal 1, stats[addr1].queued
|
@@ -64,7 +64,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
64
64
|
assert_equal 0, stats[addr2].queued
|
65
65
|
assert_equal 0, stats[addr2].active
|
66
66
|
|
67
|
-
|
67
|
+
@to_close << TCPSocket.new(TEST_ADDR, port2)
|
68
68
|
stats = tcp_listener_stats(addrs)
|
69
69
|
assert_equal 2, stats.size
|
70
70
|
assert_equal 0, stats[addr1].queued
|
@@ -72,7 +72,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
72
72
|
assert_equal 1, stats[addr2].queued
|
73
73
|
assert_equal 0, stats[addr2].active
|
74
74
|
|
75
|
-
|
75
|
+
@to_close << TCPSocket.new(TEST_ADDR, port2)
|
76
76
|
stats = tcp_listener_stats(addrs)
|
77
77
|
assert_equal 2, stats.size
|
78
78
|
assert_equal 0, stats[addr1].queued
|
@@ -80,7 +80,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
80
80
|
assert_equal 2, stats[addr2].queued
|
81
81
|
assert_equal 0, stats[addr2].active
|
82
82
|
|
83
|
-
|
83
|
+
@to_close << s2.accept
|
84
84
|
stats = tcp_listener_stats(addrs)
|
85
85
|
assert_equal 2, stats.size
|
86
86
|
assert_equal 0, stats[addr1].queued
|
@@ -116,7 +116,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
116
116
|
fork do
|
117
117
|
rda.close
|
118
118
|
wrb.close
|
119
|
-
|
119
|
+
@to_close.concat((1..nr_sock).map { s.accept })
|
120
120
|
wra.syswrite('.')
|
121
121
|
wra.close
|
122
122
|
rdb.sysread(1) # wait for parent to nuke us
|
@@ -127,7 +127,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
127
127
|
fork do
|
128
128
|
rda.close
|
129
129
|
wrb.close
|
130
|
-
|
130
|
+
@to_close.concat((1..nr_sock).map { TCPSocket.new(TEST_ADDR, port) })
|
131
131
|
wra.syswrite('.')
|
132
132
|
wra.close
|
133
133
|
rdb.sysread(1) # wait for parent to nuke us
|
@@ -141,7 +141,7 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
141
141
|
expect = { addr => Raindrops::ListenStats[nr_sock * nr_proc, 0] }
|
142
142
|
assert_equal expect, stats
|
143
143
|
|
144
|
-
|
144
|
+
@to_close << TCPSocket.new(TEST_ADDR, port)
|
145
145
|
stats = tcp_listener_stats(addrs)
|
146
146
|
expect = { addr => Raindrops::ListenStats[nr_sock * nr_proc, 1] }
|
147
147
|
assert_equal expect, stats
|
@@ -153,6 +153,6 @@ class TestLinuxIPv6 < Test::Unit::TestCase
|
|
153
153
|
|
154
154
|
wrb.syswrite('.' * (nr_proc * 2)) # broadcast a wakeup
|
155
155
|
statuses = Process.waitall
|
156
|
-
statuses.each { |(
|
156
|
+
statuses.each { |(_,status)| assert status.success?, status.inspect }
|
157
157
|
end if ENV["STRESS"].to_i != 0
|
158
158
|
end if RUBY_PLATFORM =~ /linux/ && ipv6_enabled?
|
@@ -11,12 +11,17 @@ class TestLinuxMiddleware < Test::Unit::TestCase
|
|
11
11
|
@resp_headers = { 'Content-Type' => 'text/plain', 'Content-Length' => '0' }
|
12
12
|
@response = [ 200, @resp_headers, [] ]
|
13
13
|
@app = lambda { |env| @response }
|
14
|
+
@to_close = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@to_close.each { |io| io.close unless io.closed? }
|
14
19
|
end
|
15
20
|
|
16
21
|
def test_unix_listener
|
17
22
|
tmp = Tempfile.new("")
|
18
23
|
File.unlink(tmp.path)
|
19
|
-
|
24
|
+
@to_close << UNIXServer.new(tmp.path)
|
20
25
|
app = Raindrops::Middleware.new(@app, :listeners => [tmp.path])
|
21
26
|
linux_extra = "#{tmp.path} active: 0\n#{tmp.path} queued: 0\n"
|
22
27
|
response = app.call("PATH_INFO" => "/_raindrops")
|
@@ -37,8 +42,8 @@ class TestLinuxMiddleware < Test::Unit::TestCase
|
|
37
42
|
def test_unix_listener_queued
|
38
43
|
tmp = Tempfile.new("")
|
39
44
|
File.unlink(tmp.path)
|
40
|
-
|
41
|
-
|
45
|
+
@to_close << UNIXServer.new(tmp.path)
|
46
|
+
@to_close << UNIXSocket.new(tmp.path)
|
42
47
|
app = Raindrops::Middleware.new(@app, :listeners => [tmp.path])
|
43
48
|
linux_extra = "#{tmp.path} active: 0\n#{tmp.path} queued: 1\n"
|
44
49
|
response = app.call("PATH_INFO" => "/_raindrops")
|
data/test/test_linux_tcp_info.rb
CHANGED
@@ -49,7 +49,7 @@ class TestLinuxTCP_Info < Test::Unit::TestCase
|
|
49
49
|
s = TCPServer.new(TEST_ADDR, 0)
|
50
50
|
c = TCPSocket.new TEST_ADDR, s.addr[1]
|
51
51
|
c.syswrite "."
|
52
|
-
sleep
|
52
|
+
sleep(delay * 1.2)
|
53
53
|
a = s.accept
|
54
54
|
i = Raindrops::TCP_Info.new(a)
|
55
55
|
assert i.last_data_recv >= delay_ms, "#{i.last_data_recv} < #{delay_ms}"
|
@@ -24,7 +24,7 @@ class TestMiddlewareUnicorn < Test::Unit::TestCase
|
|
24
24
|
s = TCPSocket.new @host, @port
|
25
25
|
s.write "GET /_raindrops HTTP/1.0\r\n\r\n"
|
26
26
|
resp = s.read
|
27
|
-
|
27
|
+
_, body = resp.split(/\r\n\r\n/, 2)
|
28
28
|
assert_match %r{^#@addr_regexp active: 1$}, body
|
29
29
|
assert_match %r{^#@addr_regexp queued: 0$}, body
|
30
30
|
end
|
@@ -24,7 +24,7 @@ class TestMiddlewareUnicornIPv6 < Test::Unit::TestCase
|
|
24
24
|
s = TCPSocket.new @host, @port
|
25
25
|
s.write "GET /_raindrops HTTP/1.0\r\n\r\n"
|
26
26
|
resp = s.read
|
27
|
-
|
27
|
+
_, body = resp.split(/\r\n\r\n/, 2)
|
28
28
|
assert_match %r{^#@addr_regexp active: 1$}, body
|
29
29
|
assert_match %r{^#@addr_regexp queued: 0$}, body
|
30
30
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: raindrops
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 7
|
9
|
+
- 0
|
10
|
+
version: 0.7.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- raindrops hackers
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-06-27 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: bundler
|
@@ -41,7 +40,7 @@ description: |-
|
|
41
40
|
Rubinius on platforms supporting POSIX shared memory. It may also be
|
42
41
|
used as a generic scoreboard for sharing atomic counters across multiple
|
43
42
|
processes.
|
44
|
-
email: raindrops@librelist.
|
43
|
+
email: raindrops@librelist.org
|
45
44
|
executables: []
|
46
45
|
|
47
46
|
extensions:
|
@@ -123,7 +122,6 @@ files:
|
|
123
122
|
- test/test_raindrops_gc.rb
|
124
123
|
- test/test_struct.rb
|
125
124
|
- test/test_watcher.rb
|
126
|
-
has_rdoc: true
|
127
125
|
homepage: http://raindrops.bogomips.org/
|
128
126
|
licenses: []
|
129
127
|
|
@@ -156,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
154
|
requirements: []
|
157
155
|
|
158
156
|
rubyforge_project: rainbows
|
159
|
-
rubygems_version: 1.
|
157
|
+
rubygems_version: 1.8.5
|
160
158
|
signing_key:
|
161
159
|
specification_version: 3
|
162
160
|
summary: real-time stats for preforking Rack servers
|