tupelo 0.21 → 0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +171 -45
  3. data/bin/tup +51 -0
  4. data/example/counters/merge.rb +23 -3
  5. data/example/multi-tier/multi-sinatras.rb +5 -0
  6. data/example/riemann/event-subspace.rb +1 -4
  7. data/example/riemann/expiration-dbg.rb +2 -0
  8. data/example/riemann/producer.rb +4 -3
  9. data/example/riemann/v1/riemann.rb +2 -2
  10. data/example/riemann/v2/event-template.rb +71 -0
  11. data/example/riemann/v2/expirer.rb +1 -1
  12. data/example/riemann/v2/hash-store.rb +1 -0
  13. data/example/riemann/v2/ordered-event-store.rb +4 -1
  14. data/example/riemann/v2/riemann.rb +15 -8
  15. data/example/riemann/v2/sqlite-event-store.rb +117 -72
  16. data/example/sqlite/poi-store.rb +1 -1
  17. data/example/sqlite/poi-template.rb +2 -2
  18. data/example/sqlite/poi-v2.rb +2 -2
  19. data/example/subspaces/ramp.rb +9 -2
  20. data/example/tcp.rb +5 -0
  21. data/example/tiny-tcp-client.rb +15 -0
  22. data/example/tiny-tcp-service.rb +32 -0
  23. data/lib/tupelo/app.rb +4 -4
  24. data/lib/tupelo/app/builder.rb +2 -2
  25. data/lib/tupelo/app/irb-shell.rb +3 -3
  26. data/lib/tupelo/archiver.rb +0 -2
  27. data/lib/tupelo/archiver/tuplestore.rb +1 -1
  28. data/lib/tupelo/archiver/worker.rb +6 -6
  29. data/lib/tupelo/client.rb +2 -2
  30. data/lib/tupelo/client/reader.rb +3 -3
  31. data/lib/tupelo/client/scheduler.rb +1 -1
  32. data/lib/tupelo/client/subspace.rb +2 -2
  33. data/lib/tupelo/client/transaction.rb +28 -28
  34. data/lib/tupelo/client/tuplestore.rb +2 -2
  35. data/lib/tupelo/client/worker.rb +11 -10
  36. data/lib/tupelo/util/bin-circle.rb +8 -8
  37. data/lib/tupelo/util/boolean.rb +1 -1
  38. data/lib/tupelo/version.rb +1 -1
  39. data/test/lib/mock-client.rb +10 -10
  40. data/test/system/test-archiver.rb +2 -2
  41. data/test/unit/test-ops.rb +21 -21
  42. metadata +10 -20
  43. data/example/bingo/bingo-v2.rb +0 -20
  44. data/example/broker-queue.rb +0 -35
  45. data/example/child-of-child.rb +0 -34
  46. data/example/dataflow.rb +0 -21
  47. data/example/pregel/dist-opt.rb +0 -15
  48. data/example/riemann/v2/event-sql.rb +0 -56
  49. data/example/sqlite/tmp/poi-sqlite.rb +0 -35
  50. data/example/subspaces/addr-book-v1.rb +0 -104
  51. data/example/subspaces/addr-book-v2.rb +0 -16
  52. data/example/subspaces/sorted-set-space-OLD.rb +0 -130
  53. data/lib/tupelo/tuplets/persistent-archiver.rb +0 -86
  54. data/lib/tupelo/tuplets/persistent-archiver/tuplespace.rb +0 -91
  55. data/lib/tupelo/tuplets/persistent-archiver/worker.rb +0 -114
@@ -31,7 +31,7 @@ class Tupelo::Client
31
31
  end
32
32
  end
33
33
  end
34
-
34
+
35
35
  # Tuplestore that stores nothing. Very efficient for large stores!
36
36
  # Useful for clients that don't need to take or read the stored tuples.
37
37
  # The write, pulse, and blocking read operations all work correctly.
@@ -45,7 +45,7 @@ class Tupelo::Client
45
45
  def find_distinct_matches_for(*); raise; end
46
46
  def find_match_for(*); raise; end
47
47
  def clear; end
48
-
48
+
49
49
  ## should store space metadata, so outgoing writes can be tagged
50
50
  end
51
51
  end
@@ -17,7 +17,6 @@ class Tupelo::Client
17
17
  attr_reader :msg_reader_thread
18
18
  attr_reader :worker_thread
19
19
  attr_reader :cmd_queue
20
- attr_reader :tuplestore
21
20
  attr_reader :message_class
22
21
  attr_reader :blobber
23
22
  attr_reader :read_waiters
@@ -34,7 +33,7 @@ class Tupelo::Client
34
33
  def initialize writes, pulses, takes, reads
35
34
  @writes, @pulses, @takes, @reads = writes, pulses, takes, reads
36
35
  end
37
-
36
+
38
37
  NOOP = new([].freeze, [].freeze, [].freeze, [].freeze).freeze
39
38
 
40
39
  def to_s
@@ -48,11 +47,11 @@ class Tupelo::Client
48
47
  end
49
48
  alias inspect to_s
50
49
  end
51
-
50
+
52
51
  class Subspace
53
52
  attr_reader :tag, :spec, :pot
54
53
  alias template pot
55
-
54
+
56
55
  def initialize metatuple, worker
57
56
  @metatuple = metatuple
58
57
  @tag = metatuple["tag"] || metatuple[:tag]
@@ -61,7 +60,7 @@ class Tupelo::Client
61
60
  @spec = Marshal.load(Marshal.dump(template)).freeze
62
61
  @pot = worker.pot_for(spec).optimize!.freeze
63
62
  end
64
-
63
+
65
64
  def === tuple
66
65
  @pot === tuple
67
66
  end
@@ -91,16 +90,18 @@ class Tupelo::Client
91
90
  @notify_waiters = []
92
91
  @stopping = false
93
92
  @subspaces = []
93
+
94
+ @worker_thread = nil
94
95
  end
95
96
 
96
97
  def log *args
97
98
  if args.empty?
98
99
  @log
99
100
  else
100
- @log.unknown *args
101
+ @log.unknown(*args)
101
102
  end
102
103
  end
103
-
104
+
104
105
  def tuplestore
105
106
  @tuplestore ||= begin
106
107
  if client.tuplestore.respond_to? :new
@@ -353,7 +354,7 @@ class Tupelo::Client
353
354
  log.debug {"inserting #{op.writes}; deleting #{take_tuples}"}
354
355
  tuplestore.transaction inserts: write_tuples, deletes: take_tuples,
355
356
  tick: @global_tick
356
-
357
+
357
358
  op.writes.each do |tuple|
358
359
  sniff_meta_tuple tuple
359
360
  end
@@ -539,7 +540,7 @@ class Tupelo::Client
539
540
  read_waiters << waiter
540
541
  end
541
542
  else
542
- tuplestore.each {|tuple| waiter.gloms tuple}
543
+ tuplestore.each {|t| waiter.gloms t}
543
544
  read_waiters << waiter
544
545
  end
545
546
  end
@@ -582,7 +583,7 @@ class Tupelo::Client
582
583
  pulses = transaction.pulses
583
584
  takes = transaction.take_tuples_for_remote.compact
584
585
  reads = transaction.read_tuples_for_remote.compact
585
-
586
+
586
587
  unless msg.tags
587
588
  tags = nil
588
589
  [takes, reads].compact.flatten(1).each do |tuple|
@@ -29,31 +29,31 @@ class BinCircle
29
29
  KEY_BITS = 30
30
30
  KEY_MAX = 2**KEY_BITS - 1
31
31
  DEFAULT_REPS = 10
32
-
32
+
33
33
  attr_accessor :default_reps
34
34
 
35
35
  def initialize reps: DEFAULT_REPS
36
36
  @tree = MultiRBTree.new # hashed_bin_id => bin_id
37
37
  @default_reps = reps
38
38
  end
39
-
39
+
40
40
  # +id+ should be an identifier for your bin, typically a number or string.
41
41
  # Uses id.to_s, so +id+ should not contain a hash (which would not determine
42
42
  # a unique string).
43
43
  def add_bin id, reps: default_reps
44
44
  rep_id = "#{id} 0000"
45
- reps.times do |i|
45
+ reps.times do
46
46
  key = key_for_string(rep_id)
47
47
  @tree[key] = id
48
48
  rep_id.succ!
49
49
  end
50
50
  end
51
-
51
+
52
52
  # Returns the set of bin ids now in the circle.
53
53
  def bins
54
54
  Set.new @tree.values
55
55
  end
56
-
56
+
57
57
  def inspect
58
58
  "#<#{self.class} bins=#{bins.to_a}>"
59
59
  end
@@ -64,19 +64,19 @@ class BinCircle
64
64
  def key_for_string str
65
65
  Digest::MD5.hexdigest(str).to_i(16) & KEY_MAX
66
66
  end
67
-
67
+
68
68
  # Delete the bin specified by +id+ (same as argument to #add_bin).
69
69
  def delete_bin id
70
70
  @tree.delete_if {|k,v| v == id}
71
71
  end
72
-
72
+
73
73
  # +id+ should be an identifier for your object, typically a number or string.
74
74
  # Uses id.to_s, so +id+ should not contain a hash (which would not determine
75
75
  # a unique string). It is not necessary for +id+ to be unique across objects.
76
76
  def find_bin obj
77
77
  find_bin_by_key(key_for_string(obj.to_s))
78
78
  end
79
-
79
+
80
80
  def find_bin_by_key key
81
81
  _, id = @tree.lower_bound(key) || @tree.first
82
82
  id
@@ -10,7 +10,7 @@ class Tupelo::Client
10
10
  templates.any? {|template| template === obj}
11
11
  end
12
12
  end
13
-
13
+
14
14
  def or *templates
15
15
  Or.new(worker, templates)
16
16
  end
@@ -1,3 +1,3 @@
1
1
  module Tupelo
2
- VERSION = "0.21"
2
+ VERSION = "0.22"
3
3
  end
@@ -25,16 +25,16 @@ class MockClient
25
25
  def update
26
26
  worker.update
27
27
  end
28
-
28
+
29
29
  def make_queue
30
30
  MockQueue.new
31
31
  end
32
-
33
- def will &block
34
- (@will_do ||= []) << Fiber.new { instance_eval &block }
32
+
33
+ def will(&block)
34
+ (@will_do ||= []) << Fiber.new { instance_eval(&block) }
35
35
  self
36
36
  end
37
-
37
+
38
38
  def step
39
39
  loop do
40
40
  fiber = @will_do[0] or raise IsDone, "nothing to do"
@@ -49,7 +49,7 @@ class MockClient
49
49
  @will_do.shift
50
50
  end
51
51
  end
52
-
52
+
53
53
  def run limit: 100
54
54
  loop do
55
55
  fiber = @will_do[0] or raise IsDone, "nothing to do"
@@ -77,7 +77,7 @@ class MockClient
77
77
  @will_do.shift
78
78
  end
79
79
  end
80
-
80
+
81
81
  def run_until_blocked limit: 100, &block
82
82
  begin
83
83
  run limit: limit, &block
@@ -86,9 +86,9 @@ class MockClient
86
86
  end
87
87
  raise IsDone, "run_until_blocked never blocked"
88
88
  end
89
-
89
+
90
90
  def now limit: 100, &block
91
- fiber = Fiber.new { instance_eval &block }
91
+ fiber = Fiber.new { instance_eval(&block) }
92
92
  val = nil
93
93
  count = 0
94
94
  update
@@ -106,7 +106,7 @@ class MockClient
106
106
  end
107
107
  val
108
108
  end
109
-
109
+
110
110
  def subscribed_all
111
111
  true
112
112
  end
@@ -4,9 +4,9 @@ Tupelo.application do
4
4
  expected = [[1], [2], [3]]
5
5
 
6
6
  local do
7
- write *expected
7
+ write(*expected)
8
8
  end
9
-
9
+
10
10
  child_pid = child do
11
11
  # Test that tuples written before this client started are readable.
12
12
  a = read_all [Integer]
@@ -40,14 +40,14 @@ class TestOps < Minitest::Test
40
40
  def make_clients n
41
41
  n.times.map {|i| make_client i}
42
42
  end
43
-
43
+
44
44
  def test_one_client
45
45
  client = make_client "one"
46
46
 
47
47
  client.update; writer = client.write_nowait [1]
48
48
  client.update; writer.wait
49
49
  client.update; assert_equal 1, writer.global_tick
50
-
50
+
51
51
  reader = Fiber.new do
52
52
  client.read [nil]
53
53
  end
@@ -55,11 +55,11 @@ class TestOps < Minitest::Test
55
55
  client.update; reader.resume
56
56
  client.update; assert_equal [1], reader.resume
57
57
  end
58
-
58
+
59
59
  def test_read_existing
60
60
  t = ["foo"]
61
61
  cl = make_clients(2)
62
-
62
+
63
63
  w = cl[0].now {write t}
64
64
  assert_equal 1, w.global_tick
65
65
 
@@ -129,7 +129,7 @@ class TestOps < Minitest::Test
129
129
  def test_take_waiting
130
130
  t = ["bar"]
131
131
  taker, writer = make_clients(2)
132
-
132
+
133
133
  taker.will {take [nil]}.run_until_blocked
134
134
 
135
135
  w = writer.now {write t}
@@ -142,14 +142,14 @@ class TestOps < Minitest::Test
142
142
  assert_empty c.run
143
143
  end
144
144
  end
145
-
145
+
146
146
  def test_transaction_existing
147
147
  r = [0]; w = [1]; t = [2]
148
148
  writer, transactor = make_clients(2)
149
149
 
150
150
  w_op = writer.now {write r, t}
151
151
  assert_equal 1, w_op.global_tick
152
-
152
+
153
153
  transactor.will do
154
154
  transaction do
155
155
  write w
@@ -164,7 +164,7 @@ class TestOps < Minitest::Test
164
164
  assert_equal [r, w], c.run
165
165
  end
166
166
  end
167
-
167
+
168
168
  def test_transaction_waiting
169
169
  r = [0]; w = [1]; t = [2]
170
170
  writer, transactor = make_clients(2)
@@ -179,7 +179,7 @@ class TestOps < Minitest::Test
179
179
 
180
180
  w_op = writer.now {write r, t}
181
181
  assert_equal 1, w_op.global_tick
182
-
182
+
183
183
  assert_equal [r, t], transactor.run
184
184
 
185
185
  [writer, transactor].each do |c|
@@ -187,12 +187,12 @@ class TestOps < Minitest::Test
187
187
  assert_equal [r, w], c.run
188
188
  end
189
189
  end
190
-
190
+
191
191
  def test_transaction_take_two
192
192
  x = [0]; y = [1]
193
193
  c = make_client(1)
194
194
 
195
- w_op = c.now {write x, y}
195
+ c.now {write x, y}
196
196
 
197
197
  c.will do
198
198
  transaction do
@@ -202,12 +202,12 @@ class TestOps < Minitest::Test
202
202
 
203
203
  assert_equal [x, y].sort, c.run.sort
204
204
  end
205
-
205
+
206
206
  def test_transaction_take_read
207
207
  x = [0]
208
208
  c = make_client(1)
209
209
 
210
- w_op = c.now {write x}
210
+ c.now {write x}
211
211
 
212
212
  c.will do
213
213
  transaction do
@@ -217,7 +217,7 @@ class TestOps < Minitest::Test
217
217
 
218
218
  assert_equal [x, nil], c.run
219
219
  end
220
-
220
+
221
221
  def test_transaction_write_read
222
222
  x = [0]
223
223
  c = make_client(1)
@@ -255,7 +255,7 @@ class TestOps < Minitest::Test
255
255
  assert_equal nil, transactor.run
256
256
  assert_equal 0, transactor.worker.global_tick
257
257
  end
258
-
258
+
259
259
  def test_transaction_cancel
260
260
  w = [1]; t = [2]
261
261
  writer, transactor = make_clients(2)
@@ -283,11 +283,11 @@ class TestOps < Minitest::Test
283
283
  assert_equal [t], c.run
284
284
  end
285
285
  end
286
-
286
+
287
287
  def test_transaction_fail_retry
288
288
  winner, loser = make_clients(2)
289
289
  winner.now {write ["token", 1]}
290
-
290
+
291
291
  run_count = 0
292
292
  result = nil
293
293
  loser.will do
@@ -304,7 +304,7 @@ class TestOps < Minitest::Test
304
304
  end
305
305
  loser.run_until_blocked
306
306
  assert_equal 1, run_count
307
-
307
+
308
308
  winner.will do
309
309
  take ["token", 1]
310
310
  end
@@ -316,14 +316,14 @@ class TestOps < Minitest::Test
316
316
 
317
317
  winner.now {write ["token", 2]}
318
318
  assert_raises(MockClient::IsBlocked) {loser.run}
319
-
319
+
320
320
  winner.now {write ["token", 1]}
321
321
  assert_equal [["token", 1], ["token", 2]], loser.run
322
-
322
+
323
323
  result = winner.now {read_all [nil, nil]}
324
324
  assert_equal [["test", 1], ["test", 2], ["test", 3]], result
325
325
  end
326
-
326
+
327
327
  def test_pulse
328
328
  t = ["c0"]
329
329
  reader, pulser = make_clients(2)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tupelo
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.21'
4
+ version: '0.22'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel VanderWerf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-19 00:00:00.000000000 Z
11
+ date: 2014-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: atdo
@@ -95,17 +95,14 @@ files:
95
95
  - example/balance-xfer.rb
96
96
  - example/barrier.rb
97
97
  - example/bingo/bingo-v1.rb
98
- - example/bingo/bingo-v2.rb
99
98
  - example/boolean-match.rb
100
99
  - example/bounded-retry.rb
101
100
  - example/broker-locking.rb
102
101
  - example/broker-optimistic-v2.rb
103
102
  - example/broker-optimistic.rb
104
- - example/broker-queue.rb
105
103
  - example/cancel.rb
106
104
  - example/chat/chat-nohistory.rb
107
105
  - example/chat/chat.rb
108
- - example/child-of-child.rb
109
106
  - example/concurrent-transactions.rb
110
107
  - example/consistent-hash.rb
111
108
  - example/counters/lock.rb
@@ -113,7 +110,6 @@ files:
113
110
  - example/counters/optimistic.rb
114
111
  - example/custom-class.rb
115
112
  - example/custom-search.rb
116
- - example/dataflow.rb
117
113
  - example/deadlock.rb
118
114
  - example/dedup.rb
119
115
  - example/dphil-optimistic-v2.rb
@@ -144,7 +140,6 @@ files:
144
140
  - example/observer.rb
145
141
  - example/optimist.rb
146
142
  - example/parallel.rb
147
- - example/pregel/dist-opt.rb
148
143
  - example/pregel/distributed.rb
149
144
  - example/pregel/pagerank.rb
150
145
  - example/pregel/pregel.rb
@@ -159,7 +154,7 @@ files:
159
154
  - example/riemann/producer.rb
160
155
  - example/riemann/v1/expirer.rb
161
156
  - example/riemann/v1/riemann.rb
162
- - example/riemann/v2/event-sql.rb
157
+ - example/riemann/v2/event-template.rb
163
158
  - example/riemann/v2/expirer.rb
164
159
  - example/riemann/v2/hash-store.rb
165
160
  - example/riemann/v2/http-mode.rb
@@ -174,16 +169,12 @@ files:
174
169
  - example/sqlite/poi-template.rb
175
170
  - example/sqlite/poi-v2.rb
176
171
  - example/sqlite/poi.rb
177
- - example/sqlite/tmp/poi-sqlite.rb
178
- - example/subspaces/addr-book-v1.rb
179
- - example/subspaces/addr-book-v2.rb
180
172
  - example/subspaces/addr-book.rb
181
173
  - example/subspaces/pubsub.rb
182
174
  - example/subspaces/ramp.rb
183
175
  - example/subspaces/shop/shop-v1.rb
184
176
  - example/subspaces/shop/shop-v2.rb
185
177
  - example/subspaces/simple.rb
186
- - example/subspaces/sorted-set-space-OLD.rb
187
178
  - example/subspaces/sorted-set-store.rb
188
179
  - example/take-many.rb
189
180
  - example/take-nowait-caution.rb
@@ -193,6 +184,8 @@ files:
193
184
  - example/timeout.rb
194
185
  - example/tiny-client.rb
195
186
  - example/tiny-service.rb
187
+ - example/tiny-tcp-client.rb
188
+ - example/tiny-tcp-service.rb
196
189
  - example/transaction-logic.rb
197
190
  - example/uniq-id.rb
198
191
  - example/wait-interrupt.rb
@@ -220,9 +213,6 @@ files:
220
213
  - lib/tupelo/client/transaction.rb
221
214
  - lib/tupelo/client/tuplestore.rb
222
215
  - lib/tupelo/client/worker.rb
223
- - lib/tupelo/tuplets/persistent-archiver.rb
224
- - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
225
- - lib/tupelo/tuplets/persistent-archiver/worker.rb
226
216
  - lib/tupelo/util/bin-circle.rb
227
217
  - lib/tupelo/util/boolean.rb
228
218
  - lib/tupelo/version.rb
@@ -256,9 +246,9 @@ require_paths:
256
246
  - lib
257
247
  required_ruby_version: !ruby/object:Gem::Requirement
258
248
  requirements:
259
- - - ">="
249
+ - - "~>"
260
250
  - !ruby/object:Gem::Version
261
- version: '0'
251
+ version: '2.0'
262
252
  required_rubygems_version: !ruby/object:Gem::Requirement
263
253
  requirements:
264
254
  - - ">="
@@ -266,13 +256,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
256
  version: '0'
267
257
  requirements: []
268
258
  rubyforge_project:
269
- rubygems_version: 2.2.2
259
+ rubygems_version: 2.4.1
270
260
  signing_key:
271
261
  specification_version: 4
272
262
  summary: Distributed tuplespace
273
263
  test_files:
274
- - test/unit/test-ops.rb
275
- - test/unit/test-mock-client.rb
276
264
  - test/unit/test-mock-seq.rb
277
265
  - test/unit/test-mock-queue.rb
266
+ - test/unit/test-ops.rb
267
+ - test/unit/test-mock-client.rb
278
268
  has_rdoc: