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,16 @@
1
+ # Used for running Raindrops::Watcher, which requires a multi-threaded
2
+ # Rack server capable of streaming a response. Threads must be used,
3
+ # so any multi-threaded Rack server may be used.
4
+ # zbatery was recommended in the past, but it is abandoned
5
+ # <http://zbatery.bogomip.org/>.
6
+ # yahns may work as an alternative (see yahns.conf.rb in this dir)
7
+ Rainbows! do
8
+ use :ThreadSpawn
9
+ end
10
+ log_dir = "/var/log/zbatery"
11
+ if File.writable?(log_dir) && File.directory?(log_dir)
12
+ stderr_path "#{log_dir}/raindrops-demo.stderr.log"
13
+ stdout_path "#{log_dir}/raindrops-demo.stdout.log"
14
+ listen "/tmp/.r"
15
+ pid "/tmp/.raindrops.pid"
16
+ end
@@ -0,0 +1,163 @@
1
+ require 'mkmf'
2
+ require 'shellwords'
3
+
4
+ $CFLAGS += ' -O0 ' # faster checks
5
+ dir_config('atomic_ops')
6
+ have_func('mmap', 'sys/mman.h') or abort 'mmap() not found'
7
+ have_func('munmap', 'sys/mman.h') or abort 'munmap() not found'
8
+ have_func('rb_io_descriptor')
9
+
10
+ $CPPFLAGS += " -D_GNU_SOURCE "
11
+ have_func('mremap', 'sys/mman.h')
12
+ headers = %w(sys/types.h netdb.h string.h sys/socket.h netinet/in.h)
13
+ if have_header('linux/tcp.h')
14
+ headers << 'linux/tcp.h'
15
+ else
16
+ %w(netinet/tcp.h netinet/tcp_fsm.h).each { |h|
17
+ have_header(h, headers) and headers << h
18
+ }
19
+ end
20
+
21
+ $CPPFLAGS += " -D_BSD_SOURCE "
22
+
23
+ if have_type("struct tcp_info", headers)
24
+ %w(
25
+ tcpi_state
26
+ tcpi_ca_state
27
+ tcpi_retransmits
28
+ tcpi_probes
29
+ tcpi_backoff
30
+ tcpi_options
31
+ tcpi_snd_wscale
32
+ tcpi_rcv_wscale
33
+ tcpi_rto
34
+ tcpi_ato
35
+ tcpi_snd_mss
36
+ tcpi_rcv_mss
37
+ tcpi_unacked
38
+ tcpi_sacked
39
+ tcpi_lost
40
+ tcpi_retrans
41
+ tcpi_fackets
42
+ tcpi_last_data_sent
43
+ tcpi_last_ack_sent
44
+ tcpi_last_data_recv
45
+ tcpi_last_ack_recv
46
+ tcpi_pmtu
47
+ tcpi_rcv_ssthresh
48
+ tcpi_rtt
49
+ tcpi_rttvar
50
+ tcpi_snd_ssthresh
51
+ tcpi_snd_cwnd
52
+ tcpi_advmss
53
+ tcpi_reordering
54
+ tcpi_rcv_rtt
55
+ tcpi_rcv_space
56
+ tcpi_total_retrans
57
+ tcpi_snd_wnd
58
+ tcpi_snd_bwnd
59
+ tcpi_snd_nxt
60
+ tcpi_rcv_nxt
61
+ tcpi_toe_tid
62
+ tcpi_snd_rexmitpack
63
+ tcpi_rcv_ooopack
64
+ tcpi_snd_zerowin
65
+ ).each do |field|
66
+ cfunc = "tcp_info_#{field}"
67
+ if have_struct_member('struct tcp_info', field, headers)
68
+ func_body = <<EOF
69
+ static VALUE #{cfunc}(VALUE self)
70
+ {
71
+ struct tcp_info *info = DATA_PTR(self);
72
+ return UINT2NUM((uint32_t)info->#{field});
73
+ }
74
+ EOF
75
+ func_body.delete!("\n")
76
+ $defs << "-DCFUNC_#{cfunc}=#{Shellwords.shellescape(func_body)}"
77
+ else
78
+ func_body = "static inline void #{cfunc}(void) {}"
79
+ $defs << "-DCFUNC_#{cfunc}=#{Shellwords.shellescape(func_body)}"
80
+ cfunc = 'rb_f_notimplement'.freeze
81
+ end
82
+ rbmethod = %Q("#{field.sub(/\Atcpi_/, ''.freeze)}")
83
+ $defs << "-DDEFINE_METHOD_tcp_info_#{field}=" \
84
+ "#{Shellwords.shellescape(
85
+ %Q[rb_define_method(cTCP_Info,#{rbmethod},#{cfunc},0)])}"
86
+ end
87
+ tcp_state_map = {
88
+ ESTABLISHED: %w(TCP_ESTABLISHED TCPS_ESTABLISHED),
89
+ SYN_SENT: %w(TCP_SYN_SENT TCPS_SYN_SENT),
90
+ SYN_RECV: %w(TCP_SYN_RECV TCPS_SYN_RECEIVED),
91
+ FIN_WAIT1: %w(TCP_FIN_WAIT1 TCPS_FIN_WAIT_1),
92
+ FIN_WAIT2: %w(TCP_FIN_WAIT2 TCPS_FIN_WAIT_2),
93
+ TIME_WAIT: %w(TCP_TIME_WAIT TCPS_TIME_WAIT),
94
+ CLOSE: %w(TCP_CLOSE TCPS_CLOSED),
95
+ CLOSE_WAIT: %w(TCP_CLOSE_WAIT TCPS_CLOSE_WAIT),
96
+ LAST_ACK: %w(TCP_LAST_ACK TCPS_LAST_ACK),
97
+ LISTEN: %w(TCP_LISTEN TCPS_LISTEN),
98
+ CLOSING: %w(TCP_CLOSING TCPS_CLOSING),
99
+ }
100
+ nstate = 0
101
+ tcp_state_map.each do |state, try|
102
+ try.each do |os_name|
103
+ have_const(os_name, headers) or next
104
+ tcp_state_map[state] = os_name
105
+ nstate += 1
106
+ end
107
+ end
108
+ if nstate == tcp_state_map.size
109
+ $defs << '-DRAINDROPS_TCP_STATES_ALL_KNOWN=1'
110
+ tcp_state_map.each do |state, name|
111
+ $defs << "-DRAINDROPS_TCP_#{state}=#{name}"
112
+ end
113
+ end
114
+ end
115
+
116
+ have_func("getpagesize", "unistd.h")
117
+ have_func('rb_thread_call_without_gvl')
118
+ have_func('rb_thread_blocking_region')
119
+ have_func('rb_thread_io_blocking_region')
120
+
121
+ checking_for "GCC 4+ atomic builtins" do
122
+ # we test CMPXCHG anyways even though we don't need it to filter out
123
+ # ancient i386-only targets without CMPXCHG
124
+ src = <<SRC
125
+ int main(int argc, char * const argv[]) {
126
+ unsigned long i = 0;
127
+ __sync_lock_test_and_set(&i, 0);
128
+ __sync_lock_test_and_set(&i, 1);
129
+ __sync_bool_compare_and_swap(&i, 0, 1);
130
+ __sync_add_and_fetch(&i, argc);
131
+ __sync_sub_and_fetch(&i, argc);
132
+ return 0;
133
+ }
134
+ SRC
135
+
136
+ if try_link(src)
137
+ $defs.push(format("-DHAVE_GCC_ATOMIC_BUILTINS"))
138
+ true
139
+ else
140
+ # some compilers still target 386 by default, but we need at least 486
141
+ # to run atomic builtins.
142
+ prev_cflags = $CFLAGS
143
+ $CFLAGS += " -march=i486 "
144
+ if try_link(src)
145
+ $defs.push(format("-DHAVE_GCC_ATOMIC_BUILTINS"))
146
+ true
147
+ else
148
+ $CFLAGS = prev_cflags
149
+ false
150
+ end
151
+ end
152
+ end or have_header('atomic_ops.h') or abort <<-SRC
153
+
154
+ libatomic_ops is required if GCC 4+ is not used.
155
+ See https://github.com/ivmai/libatomic_ops
156
+
157
+ Users of Debian-based distros may run:
158
+
159
+ apt-get install libatomic-ops-dev
160
+ SRC
161
+ create_header # generate extconf.h to avoid excessively long command-line
162
+ $CFLAGS.sub!(/ -O0 /, '')
163
+ create_makefile('raindrops_ext')