raindrops 0.19.1 → 0.20.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c5318918bfd5808ecc840404c67ed59f80019c6a705ef434b10ae92da78ba06
4
- data.tar.gz: 1f25061c601aab07e3eb041cc9c2fd005438a1527994e0696b5eafc8dc148650
3
+ metadata.gz: 6f78e29ec57e3f3710146a423cf60915d23a5f4366d70dcabbbef74fb69f71f3
4
+ data.tar.gz: 8a369d49c33a67af3b6acccaf64b04ed192cba9d163c8d48944cfac887511885
5
5
  SHA512:
6
- metadata.gz: df8be08761d8444a8599da3a5885efc806df935820753f5b000f27ab408171438b0f6ff4650810b5096e648904f5993bbc2a1303b9571df213201919b4b7f565
7
- data.tar.gz: 250b7236881f06fdd684b22f4844cacb7a0d2ca43703220fe3f0f4ebc49e51faf2015864ef6776edc0d66c7dfd2762e08145548a5dd06b55c2193e989f21a3fd
6
+ metadata.gz: b9e5de8e7a7a84038bbe19a954d3d559ebec3ed4c7f68db2e2ada6373b045f4fbcd784c5d5b91005cad1d87f1db93f9dc31c9f7fc59ae56a7f73b98d9a96bf2e
7
+ data.tar.gz: 9913e9205b2527b9f5bd1bae58b0c2c8962505e87280c06257f603fb722978d6656c99cfa0a297ccd0734a7d6110b0a6ecd5155fec9870ec40a31044a00def4d
data/.olddoc.yml CHANGED
@@ -4,10 +4,13 @@ rdoc_url: https://yhbt.net/raindrops/
4
4
  public_email: raindrops-public@yhbt.net
5
5
  ml_url:
6
6
  - https://yhbt.net/raindrops-public/
7
- - http://ou63pmih66umazou.onion/raindrops-public
7
+ - http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/raindrops-public
8
+ imap_url:
9
+ - imaps://yhbt.net/inbox.comp.lang.ruby.raindrops.0
10
+ - imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.raindrops.0
8
11
  nntp_url:
9
- - nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
10
- - nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.raindrops
12
+ - nntps://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
13
+ - nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.raindrops
11
14
  source_code:
12
15
  - git clone https://yhbt.net/raindrops.git
13
- - torsocks git clone http://ou63pmih66umazou.onion/raindrops.git
16
+ - torsocks git clone http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/raindrops.git
data/GIT-VERSION-FILE CHANGED
@@ -1 +1 @@
1
- GIT_VERSION = 0.19.1
1
+ GIT_VERSION = 0.20.0
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.19.1
4
+ DEF_VER=v0.20.0
5
5
 
6
6
  LF='
7
7
  '
data/LATEST CHANGED
@@ -1,14 +1,10 @@
1
- === raindrops 0.19.1 / 2020-01-08 09:31 UTC
1
+ === raindrops 0.20.0 / 2021-12-06 23:41 UTC
2
2
 
3
- This release fixes some warnings on newer Rubies.
3
+ Raindrops may now use file-backed mmap() rather than anonymous
4
+ memory. Thanks to KJ Tsanaktsidis for the patch:
4
5
 
5
- We're no longer on bogomips.org since it's due
6
- for expiry and I can't pay extortionists for a .org, so
7
- s/bogomips.org/yhbt.net/ for now, and be prepared to move again
8
- when extortionists move onto extorting the .net TLD.
6
+ https://yhbt.net/raindrops-public/20211125065618.3432-1-ktsanaktsidis@zendesk.com/T/
9
7
 
10
- doc: switch homepage to dark216
11
- ext/raindrops/extconf: fix cflags reset on ancient CC
12
- fixes for newer rubies
13
- replace bogomips.org with yhbt.net
8
+ The documentation is also updated to note our mail archives are now
9
+ available via IMAP(S).
14
10
 
data/NEWS CHANGED
@@ -1,3 +1,20 @@
1
+ === raindrops 0.20.0 / 2021-12-06 23:41 UTC
2
+
3
+ Raindrops may now use file-backed mmap() rather than anonymous
4
+ memory. Thanks to KJ Tsanaktsidis for the patch:
5
+
6
+ https://yhbt.net/raindrops-public/20211125065618.3432-1-ktsanaktsidis@zendesk.com/T/
7
+
8
+ The documentation is also updated to note our mail archives are now
9
+ available via IMAP(S).
10
+
11
+ === raindrops 0.19.2 / 2021-05-25 23:13 UTC
12
+
13
+ This release fixes compatibility with GC.compact on Ruby 3.x
14
+ when using ListenStats on Linux. The listener stats
15
+ functionality is rarely used and does not affect most users
16
+ who just have raindrops installed for shared atomic counters.
17
+
1
18
  === raindrops 0.19.1 / 2020-01-08 09:31 UTC
2
19
 
3
20
  This release fixes some warnings on newer Rubies.
data/README CHANGED
@@ -58,24 +58,20 @@ If you use RubyGems:
58
58
 
59
59
  See Raindrops::Middleware and Raindrops::LastDataRecv documentation for
60
60
  use Rack servers. The entire library is fully-documented and we are
61
- responsive on the publically archived mailing list
62
- (mailto:raindrops-public@yhbt.net) if
63
- you have any questions or comments.
61
+ responsive on the publicly archived mailbox
62
+ (mailto:raindrops-public@yhbt.net) if you have any questions or comments.
64
63
 
65
64
  == Development
66
65
 
67
66
  You can get the latest source via git from the following locations:
68
67
 
69
- git://yhbt.net/raindrops.git
70
- git://repo.or.cz/raindrops.git (mirror)
68
+ https://yhbt.net/raindrops.git
69
+ http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/raindrops.git
70
+ http://repo.or.cz/w/raindrops.git (gitweb mirror)
71
71
 
72
- You may browse the code from the web and download the latest snapshot
73
- tarballs here:
72
+ Snapshots and tarballs are available.
74
73
 
75
- * https://yhbt.net/raindrops.git
76
- * http://repo.or.cz/w/raindrops.git (gitweb)
77
-
78
- Inline patches (from "git format-patch") to the mailing list are
74
+ Inline patches (from "git format-patch") to the mailbox are
79
75
  preferred because they allow code review and comments in the reply to
80
76
  the patch.
81
77
 
@@ -89,14 +85,17 @@ raindrops is licensed under the LGPL-2.1+
89
85
  == Contact
90
86
 
91
87
  All feedback (bug reports, user/development discussion, patches, pull
92
- requests) go to the publically archived mailing list:
88
+ requests) go to the publicly archived mailbox:
93
89
  mailto:raindrops-public@yhbt.net
94
90
 
95
- Mailing list archives are available over HTTPS and NNTP:
91
+ Mail archives are available over HTTP(S), IMAP(S) and NNTP(S):
96
92
 
97
93
  * https://yhbt.net/raindrops-public/
98
- * http://ou63pmih66umazou.onion/raindrops-public/
99
- * nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
94
+ * http://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/raindrops-public/
95
+ * imaps://yhbt.net/inbox.comp.lang.ruby.raindrops.0
96
+ * imap://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.raindrops.0
97
+ * nntps://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
98
+ * nntp://7fh6tueqddpjyxjmgtdiueylzoqt6pt7hec3pukyptlmohoowvhde4yd.onion/inbox.comp.lang.ruby.raindrops
100
99
 
101
100
  Since archives are public, scrub sensitive information and
102
101
  use anonymity tools such as Tor or Mixmaster if you deem necessary.
@@ -696,6 +696,7 @@ void Init_raindrops_linux_inet_diag(void)
696
696
  rb_define_singleton_method(cIDSock, "new", ids_s_new, 0);
697
697
 
698
698
  cListenStats = rb_const_get(cRaindrops, rb_intern("ListenStats"));
699
+ rb_gc_register_mark_object(cListenStats); /* pin */
699
700
 
700
701
  rb_define_module_function(mLinux, "tcp_listener_stats",
701
702
  tcp_listener_stats, -1);
@@ -4,6 +4,7 @@
4
4
  #include <assert.h>
5
5
  #include <errno.h>
6
6
  #include <stddef.h>
7
+ #include <string.h>
7
8
  #include "raindrops_atomic.h"
8
9
 
9
10
  #ifndef SIZET2NUM
@@ -34,9 +35,17 @@ struct raindrops {
34
35
  size_t size;
35
36
  size_t capa;
36
37
  pid_t pid;
38
+ VALUE io;
37
39
  struct raindrop *drops;
38
40
  };
39
41
 
42
+ /* called by GC */
43
+ static void rd_mark(void *ptr)
44
+ {
45
+ struct raindrops *r = ptr;
46
+ rb_gc_mark(r->io);
47
+ }
48
+
40
49
  /* called by GC */
41
50
  static void rd_free(void *ptr)
42
51
  {
@@ -60,7 +69,7 @@ static size_t rd_memsize(const void *ptr)
60
69
 
61
70
  static const rb_data_type_t rd_type = {
62
71
  "raindrops",
63
- { NULL, rd_free, rd_memsize, /* reserved */ },
72
+ { rd_mark, rd_free, rd_memsize, /* reserved */ },
64
73
  /* parent, data, [ flags ] */
65
74
  };
66
75
 
@@ -87,16 +96,10 @@ static struct raindrops *get(VALUE self)
87
96
  }
88
97
 
89
98
  /*
90
- * call-seq:
91
- * Raindrops.new(size) -> raindrops object
92
- *
93
- * Initializes a Raindrops object to hold +size+ counters. +size+ is
94
- * only a hint and the actual number of counters the object has is
95
- * dependent on the CPU model, number of cores, and page size of
96
- * the machine. The actual size of the object will always be equal
97
- * or greater than the specified +size+.
99
+ * This is the _actual_ implementation of #initialize - the Ruby wrapper
100
+ * handles keyword-argument handling then calls this method.
98
101
  */
99
- static VALUE init(VALUE self, VALUE size)
102
+ static VALUE init_cimpl(VALUE self, VALUE size, VALUE io, VALUE zero)
100
103
  {
101
104
  struct raindrops *r = DATA_PTR(self);
102
105
  int tries = 1;
@@ -113,9 +116,19 @@ static VALUE init(VALUE self, VALUE size)
113
116
  r->capa = tmp / raindrop_size;
114
117
  assert(PAGE_ALIGN(raindrop_size * r->capa) == tmp && "not aligned");
115
118
 
119
+ r->io = io;
120
+
116
121
  retry:
117
- r->drops = mmap(NULL, tmp,
118
- PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
122
+ if (RTEST(r->io)) {
123
+ int fd = NUM2INT(rb_funcall(r->io, rb_intern("fileno"), 0));
124
+ rb_funcall(r->io, rb_intern("truncate"), 1, SIZET2NUM(tmp));
125
+ r->drops = mmap(NULL, tmp,
126
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
127
+ } else {
128
+ r->drops = mmap(NULL, tmp,
129
+ PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
130
+ -1, 0);
131
+ }
119
132
  if (r->drops == MAP_FAILED) {
120
133
  int err = errno;
121
134
 
@@ -127,6 +140,9 @@ retry:
127
140
  }
128
141
  r->pid = getpid();
129
142
 
143
+ if (RTEST(zero))
144
+ memset(r->drops, 0, tmp);
145
+
130
146
  return self;
131
147
  }
132
148
 
@@ -217,14 +233,16 @@ static VALUE capa(VALUE self)
217
233
  * call-seq:
218
234
  * rd.dup -> rd_copy
219
235
  *
220
- * Duplicates and snapshots the current state of a Raindrops object.
236
+ * Duplicates and snapshots the current state of a Raindrops object. Even
237
+ * if the given Raindrops object is backed by a file, the copy will be backed
238
+ * by independent, anonymously mapped memory.
221
239
  */
222
240
  static VALUE init_copy(VALUE dest, VALUE source)
223
241
  {
224
242
  struct raindrops *dst = DATA_PTR(dest);
225
243
  struct raindrops *src = get(source);
226
244
 
227
- init(dest, SIZET2NUM(src->size));
245
+ init_cimpl(dest, SIZET2NUM(src->size), Qnil, Qfalse);
228
246
  memcpy(dst->drops, src->drops, raindrop_size * src->size);
229
247
 
230
248
  return dest;
@@ -375,6 +393,20 @@ static VALUE evaporate_bang(VALUE self)
375
393
  return Qnil;
376
394
  }
377
395
 
396
+ /*
397
+ * call-seq:
398
+ * to_io -> IO
399
+ *
400
+ * Returns the IO object backing the memory for this raindrop, if
401
+ * one was specified when constructing this Raindrop. If this
402
+ * Raindrop is backed by anonymous memory, this method returns nil.
403
+ */
404
+ static VALUE to_io(VALUE self)
405
+ {
406
+ struct raindrops *r = get(self);
407
+ return r->io;
408
+ }
409
+
378
410
  void Init_raindrops_ext(void)
379
411
  {
380
412
  VALUE cRaindrops = rb_define_class("Raindrops", rb_cObject);
@@ -433,7 +465,7 @@ void Init_raindrops_ext(void)
433
465
 
434
466
  rb_define_alloc_func(cRaindrops, alloc);
435
467
 
436
- rb_define_method(cRaindrops, "initialize", init, 1);
468
+ rb_define_private_method(cRaindrops, "initialize_cimpl", init_cimpl, 3);
437
469
  rb_define_method(cRaindrops, "incr", incr, -1);
438
470
  rb_define_method(cRaindrops, "decr", decr, -1);
439
471
  rb_define_method(cRaindrops, "to_ary", to_ary, 0);
@@ -444,6 +476,7 @@ void Init_raindrops_ext(void)
444
476
  rb_define_method(cRaindrops, "capa", capa, 0);
445
477
  rb_define_method(cRaindrops, "initialize_copy", init_copy, 1);
446
478
  rb_define_method(cRaindrops, "evaporate!", evaporate_bang, 0);
479
+ rb_define_method(cRaindrops, "to_io", to_io, 0);
447
480
 
448
481
  #ifdef __linux__
449
482
  Init_raindrops_linux_inet_diag();
data/lib/raindrops.rb CHANGED
@@ -36,6 +36,30 @@ class Raindrops
36
36
  def total
37
37
  active + queued
38
38
  end
39
+ end unless defined? ListenStats
40
+
41
+ # call-seq:
42
+ # Raindrops.new(size, io: nil) -> raindrops object
43
+ #
44
+ # Initializes a Raindrops object to hold +size+ counters. +size+ is
45
+ # only a hint and the actual number of counters the object has is
46
+ # dependent on the CPU model, number of cores, and page size of
47
+ # the machine. The actual size of the object will always be equal
48
+ # or greater than the specified +size+.
49
+ # If +io+ is provided, then the Raindrops memory will be backed by
50
+ # the specified file; otherwise, it will allocate anonymous memory.
51
+ # The IO object must respond to +truncate+, as this is used to set
52
+ # the size of the file.
53
+ # If +zero+ is provided, then the memory region is zeroed prior to
54
+ # returning. This is only meaningful if +io+ is also provided; in
55
+ # that case it controls whether any existing counter values in +io+
56
+ # are retained (false) or whether it is entirely zeroed (true).
57
+ def initialize(size, io: nil, zero: false)
58
+ # This ruby wrapper exists to handle the keyword-argument handling,
59
+ # which is otherwise kind of awkward in C. We delegate the keyword
60
+ # arguments to the _actual_ initialize implementation as positional
61
+ # args.
62
+ initialize_cimpl(size, io, zero)
39
63
  end
40
64
 
41
65
  autoload :Linux, 'raindrops/linux'
data/pkg.mk CHANGED
@@ -127,7 +127,8 @@ publish_doc:
127
127
  -git set-file-times
128
128
  $(MAKE) doc
129
129
  $(MAKE) doc_gz
130
- $(RSYNC) -av doc/ $(RSYNC_DEST)/
130
+ $(RSYNC) -av doc/ $(RSYNC_DEST)/ \
131
+ --exclude index.html* --exclude created.rid*
131
132
  git ls-files | xargs touch
132
133
  endif
133
134
 
@@ -1,6 +1,7 @@
1
1
  # -*- encoding: binary -*-
2
2
  require 'test/unit'
3
3
  require 'raindrops'
4
+ require 'tempfile'
4
5
 
5
6
  class TestRaindrops < Test::Unit::TestCase
6
7
 
@@ -162,4 +163,45 @@ class TestRaindrops < Test::Unit::TestCase
162
163
  assert status.success?
163
164
  assert_equal [ 1, 2 ], tmp.to_ary
164
165
  end
166
+
167
+ def test_io_backed
168
+ file = Tempfile.new('test_io_backed')
169
+ rd = Raindrops.new(4, io: file, zero: true)
170
+ rd[0] = 123
171
+ rd[1] = 456
172
+
173
+ assert_equal 123, rd[0]
174
+ assert_equal 456, rd[1]
175
+
176
+ rd.evaporate!
177
+
178
+ file.rewind
179
+ data = file.read
180
+ assert_equal 123, data.unpack('L!')[0]
181
+ assert_equal 456, data[Raindrops::SIZE..data.size].unpack('L!')[0]
182
+ end
183
+
184
+ def test_io_backed_reuse
185
+ file = Tempfile.new('test_io_backed')
186
+ rd = Raindrops.new(4, io: file, zero: true)
187
+ rd[0] = 123
188
+ rd[1] = 456
189
+ rd.evaporate!
190
+
191
+ rd = Raindrops.new(4, io: file, zero: false)
192
+ assert_equal 123, rd[0]
193
+ assert_equal 456, rd[1]
194
+ end
195
+
196
+ def test_iobacked_noreuse
197
+ file = Tempfile.new('test_io_backed')
198
+ rd = Raindrops.new(4, io: file, zero: true)
199
+ rd[0] = 123
200
+ rd[1] = 456
201
+ rd.evaporate!
202
+
203
+ rd = Raindrops.new(4, io: file, zero: true)
204
+ assert_equal 0, rd[0]
205
+ assert_equal 0, rd[1]
206
+ end
165
207
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: raindrops
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - raindrops hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-08 00:00:00.000000000 Z
11
+ date: 2021-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aggregate