tupelo 0.9 → 0.10

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +31 -1
  3. data/bugs/read-take.rb +19 -0
  4. data/bugs/take-write.rb +7 -7
  5. data/example/app-and-tup.rb +11 -8
  6. data/example/async-transaction.rb +7 -7
  7. data/example/balance-xfer-locking.rb +13 -13
  8. data/example/balance-xfer-retry.rb +16 -16
  9. data/example/balance-xfer.rb +9 -9
  10. data/example/boolean-match.rb +5 -5
  11. data/example/bounded-retry.rb +9 -9
  12. data/example/broker-locking.rb +14 -14
  13. data/example/broker-optimistic.rb +7 -7
  14. data/example/cancel.rb +7 -7
  15. data/example/concurrent-transactions.rb +17 -17
  16. data/example/custom-class.rb +9 -9
  17. data/example/custom-search.rb +8 -8
  18. data/example/fail-and-retry.rb +11 -11
  19. data/example/hash-tuples.rb +12 -10
  20. data/example/increment.rb +8 -8
  21. data/example/load-balancer.rb +2 -1
  22. data/example/lock-mgr-with-queue.rb +18 -18
  23. data/example/lock-mgr.rb +18 -18
  24. data/example/map-reduce-v2.rb +11 -11
  25. data/example/map-reduce.rb +11 -11
  26. data/example/matching.rb +5 -5
  27. data/example/message-bus.rb +6 -3
  28. data/example/notify.rb +17 -17
  29. data/example/optimist.rb +9 -9
  30. data/example/parallel.rb +16 -8
  31. data/example/pregel/distributed.rb +129 -0
  32. data/example/pregel/pagerank.rb +72 -0
  33. data/example/pregel/pregel.rb +102 -0
  34. data/example/pregel/remote.rb +165 -0
  35. data/example/pulse.rb +10 -10
  36. data/example/read-in-trans.rb +15 -15
  37. data/example/subspace.rb +34 -0
  38. data/example/take-nowait.rb +1 -0
  39. data/example/tcp.rb +3 -3
  40. data/example/timeout-trans.rb +5 -5
  41. data/example/timeout.rb +10 -9
  42. data/example/tiny-client.rb +5 -5
  43. data/example/tiny-server.rb +2 -2
  44. data/example/transaction-logic.rb +16 -16
  45. data/example/wait-interrupt.rb +38 -0
  46. data/example/write-wait.rb +11 -11
  47. data/lib/tupelo/archiver/tuplespace.rb +5 -1
  48. data/lib/tupelo/archiver/worker.rb +25 -18
  49. data/lib/tupelo/client/reader.rb +2 -2
  50. data/lib/tupelo/client/transaction.rb +79 -36
  51. data/lib/tupelo/client/tuplespace.rb +1 -0
  52. data/lib/tupelo/client/worker.rb +107 -13
  53. data/lib/tupelo/client.rb +36 -2
  54. data/lib/tupelo/version.rb +1 -1
  55. data/test/lib/mock-client.rb +4 -0
  56. data/test/lib/testable-worker.rb +1 -1
  57. data/test/stress/concurrent-transactions.rb +15 -15
  58. data/test/system/test-archiver.rb +8 -8
  59. data/test/unit/test-ops.rb +56 -0
  60. metadata +72 -68
  61. data/bugs/write-read.rb +0 -15
  62. data/example/broker-queue.rb +0 -35
  63. data/example/child-of-child.rb +0 -34
@@ -24,6 +24,7 @@ class Tupelo::Client
24
24
  attr_reader :prep_waiters
25
25
  attr_reader :trans_waiters
26
26
  attr_reader :notify_waiters
27
+ attr_reader :subspaces
27
28
 
28
29
  GET_TUPLESPACE = "get tuplespace"
29
30
 
@@ -36,6 +37,8 @@ class Tupelo::Client
36
37
  @atomic, @writes, @pulses, @takes, @reads =
37
38
  atomic, writes, pulses, takes, reads
38
39
  end
40
+
41
+ NOOP = new([], [], [], [], [])
39
42
 
40
43
  def to_s
41
44
  ops = [ ["write", writes], ["pulse", pulses],
@@ -49,6 +52,22 @@ class Tupelo::Client
49
52
  end
50
53
  alias inspect to_s
51
54
  end
55
+
56
+ class Subspace
57
+ attr_reader :tag
58
+
59
+ def initialize metatuple, worker
60
+ @metatuple = metatuple
61
+ @tag = metatuple["tag"]
62
+
63
+ spec = Marshal.load(Marshal.dump(metatuple["template"]))
64
+ @pot = worker.pot_for(spec).optimize!
65
+ end
66
+
67
+ def === tuple
68
+ @pot === tuple
69
+ end
70
+ end
52
71
 
53
72
  def initialize client
54
73
  @client = client
@@ -72,6 +91,7 @@ class Tupelo::Client
72
91
  @trans_waiters = []
73
92
  @notify_waiters = []
74
93
  @stopping = false
94
+ @subspaces = []
75
95
  end
76
96
 
77
97
  def log *args
@@ -202,9 +222,11 @@ class Tupelo::Client
202
222
  end
203
223
  end
204
224
 
205
- def update_to_tick tick
206
- # at this point we know that the seq messages now accumulating in
225
+ def update_to_tick tick: nil, tags: nil, all: false
226
+ # At this point we know that the seq messages now accumulating in
207
227
  # cmd_queue are tick+1, tick+2, ....
228
+ # (or a subset of this sequence if not subscribed_all).
229
+ # Some of these might get discarded later if archiver is more current.
208
230
  log.debug {"update_to_tick #{tick}"}
209
231
 
210
232
  unless arc
@@ -218,10 +240,20 @@ class Tupelo::Client
218
240
  end
219
241
 
220
242
  log.info "requesting tuplespace from arc"
221
- arc << [GET_TUPLESPACE, nil, tick]
222
- ## replace nil with tags, if any
243
+ subscription_delta = {
244
+ request_all: all,
245
+ request_tags: tags,
246
+ subscribed_all: client.subscribed_all,
247
+ subscribed_tags: client.subscribed_tags
248
+ }
249
+ arc << [GET_TUPLESPACE, subscription_delta, tick]
223
250
 
224
251
  begin
252
+ tuplespace.clear
253
+ ## in some cases, we can keep some of it, but the current
254
+ ## archiver is not smart enough to send exactly the delta
255
+ ### abort all current transactions???
256
+
225
257
  arc_tick = arc.read[0]
226
258
  log.info "arc says global_tick = #{arc_tick}"
227
259
 
@@ -232,6 +264,7 @@ class Tupelo::Client
232
264
  done = true
233
265
  else
234
266
  raise "bad object stream from archiver" if done
267
+ sniff_meta_tuple tuple
235
268
  tuplespace.insert tuple
236
269
  count += 1
237
270
  end
@@ -255,9 +288,18 @@ class Tupelo::Client
255
288
 
256
289
  if msg.control?
257
290
  client.handle_ack msg
258
- op_type, *args = msg.control_op
259
- if op_type == Funl::SUBSCRIBE_ALL
260
- update_to_tick msg.global_tick
291
+ op_type, tags = msg.control_op
292
+ case op_type
293
+ when Funl::SUBSCRIBE_ALL
294
+ update_to_tick tick: msg.global_tick, all: true
295
+ when Funl::SUBSCRIBE
296
+ update_to_tick tick: msg.global_tick,
297
+ tags: (client.subscribed_tags + tags)
298
+ when Funl::UNSUBSCRIBE_ALL
299
+ update_to_tick tick: msg.global_tick, all: false
300
+ when Funl::UNSUBSCRIBE
301
+ update_to_tick tick: msg.global_tick,
302
+ tags: (client.subscribed_tags - tags)
261
303
  else
262
304
  raise "Unimplemented: #{msg.inspect}"
263
305
  end
@@ -278,7 +320,8 @@ class Tupelo::Client
278
320
  @delta = 0
279
321
 
280
322
  record_history msg
281
- op = Operation.new(*blobber.load(msg.blob)) ## op.freeze_deeply
323
+ op = msg.blob ? Operation.new(*blobber.load(msg.blob)) : Operation::NOOP
324
+ ## op.freeze_deeply
282
325
  log.debug {"applying #{op} from client #{msg.client_id}"}
283
326
 
284
327
  notify_waiters.each do |waiter|
@@ -295,6 +338,20 @@ class Tupelo::Client
295
338
  log.debug {"inserting #{op.writes}; deleting #{actual_tuples}"}
296
339
  tuplespace.transaction inserts: op.writes, deletes: actual_tuples,
297
340
  tick: @global_tick
341
+
342
+ op.writes.each do |tuple|
343
+ sniff_meta_tuple tuple
344
+ end
345
+
346
+ actual_tuples.each do |tuple|
347
+ ### abstract this out
348
+ if tuple.kind_of? Hash and tuple.key? "__tupelo__"
349
+ if tuple["__tupelo__"] == "subspace" # tuple is subspace metatdata
350
+ ## do some error checking
351
+ subspaces.delete_if {|sp| sp.tag == tuple["tag"]}
352
+ end
353
+ end
354
+ end
298
355
  end
299
356
 
300
357
  notify_waiters.each do |waiter|
@@ -368,6 +425,16 @@ class Tupelo::Client
368
425
  end
369
426
  end
370
427
 
428
+ def sniff_meta_tuple tuple
429
+ if tuple.kind_of? Hash and tuple.key? "__tupelo__"
430
+ if tuple["__tupelo__"] == "subspace" # tuple is subspace metatdata
431
+ ## do some error checking
432
+ ## what if subspace already exists?
433
+ subspaces << Subspace.new(tuple, self)
434
+ end
435
+ end
436
+ end
437
+
371
438
  def record_history msg; end
372
439
 
373
440
  def handle_client_request req
@@ -449,15 +516,42 @@ class Tupelo::Client
449
516
  msg.local_tick = local_tick + 1
450
517
  msg.global_tick = global_tick
451
518
  msg.delta = delta + 1 # pipelined write/take
452
- ##msg.tags = nil
519
+ msg.tags = transaction.tags
520
+
521
+ writes = transaction.writes
522
+ pulses = transaction.pulses
523
+ takes = transaction.take_tuples_for_remote.compact
524
+ reads = transaction.read_tuples_for_remote.compact
525
+
526
+ unless msg.tags
527
+ tags = []
528
+ tuples = [writes, pulses, takes, reads].compact.flatten(1)
529
+ subspaces.each do |subspace|
530
+ tuples.each do |tuple|
531
+ if subspace === tuple
532
+ tags << subspace.tag
533
+ break
534
+ end
535
+ end
536
+ end
537
+
538
+ will_get_this_msg = client.subscribed_all ||
539
+ tags.any? {|tag| client.subscribed_tags.include? tag} ## optimize
540
+
541
+ unless will_get_this_msg
542
+ tags << true # reflect
543
+ end
544
+
545
+ if not tags.empty?
546
+ msg.tags = tags
547
+ log.debug {"tagged transaction: #{tags}"}
548
+ end
549
+ end
453
550
 
454
551
  begin
455
552
  msg.blob = blobber.dump([
456
553
  transaction.atomic,
457
- transaction.writes,
458
- transaction.pulses,
459
- transaction.take_tuples,
460
- transaction.read_tuples
554
+ writes, pulses, takes, reads
461
555
  ])
462
556
  ## optimization: use bitfields to identify which ops are present
463
557
  ## (instead of nils), and combine this with atomic flag in one int
data/lib/tupelo/client.rb CHANGED
@@ -10,10 +10,13 @@ module Tupelo
10
10
  attr_reader :worker
11
11
  attr_reader :tuplespace
12
12
 
13
- def initialize(tuplespace: SimpleTuplespace, **opts)
13
+ TUPELO_SUBSPACE_TAG = "tupelo subspace"
14
+
15
+ def initialize(tuplespace: SimpleTuplespace, subscribe: :all, **opts)
14
16
  super **opts
15
17
  @tuplespace = tuplespace
16
18
  @worker = make_worker
19
+ @initial_subscriptions = subscribe
17
20
  end
18
21
 
19
22
  def make_worker
@@ -27,7 +30,13 @@ module Tupelo
27
30
  def start
28
31
  super
29
32
  worker.start
30
- subscribe_all ## for now, but eventually should start without subs
33
+
34
+ case @initial_subscriptions
35
+ when :all
36
+ subscribe_all
37
+ when Array
38
+ subscribe @initial_subscriptions | [Tupelo::Client::TUPELO_SUBSPACE_TAG]
39
+ end
31
40
  end
32
41
 
33
42
  def stop
@@ -41,5 +50,30 @@ module Tupelo
41
50
  super().unknown *args
42
51
  end
43
52
  end
53
+
54
+ ## do these belong in API module?
55
+ def define_subspace metatuple
56
+ defaults = {__tupelo__: "subspace", addr: nil}
57
+ write_wait defaults.merge!(metatuple)
58
+ end
59
+
60
+ # call this just once at start of first client (it's optional to
61
+ # preserve behavior of non-subspace-aware code)
62
+ def use_subspaces!
63
+ define_subspace(
64
+ tag: TUPELO_SUBSPACE_TAG,
65
+ template: {
66
+ __tupelo__: {value: "subspace"},
67
+ tag: nil,
68
+ addr: nil,
69
+ template: nil
70
+ }
71
+ )
72
+ end
73
+
74
+ def subspace tag
75
+ tag = tag.to_s
76
+ worker.subspaces.find {|sp| sp.tag == tag}
77
+ end
44
78
  end
45
79
  end
@@ -1,3 +1,3 @@
1
1
  module Tupelo
2
- VERSION = "0.9"
2
+ VERSION = "0.10"
3
3
  end
@@ -105,4 +105,8 @@ class MockClient
105
105
  end
106
106
  val
107
107
  end
108
+
109
+ def subscribed_all
110
+ true
111
+ end
108
112
  end
@@ -8,7 +8,7 @@ class TestableWorker < Tupelo::Client::Worker
8
8
  @cmd_queue = MockQueue.new
9
9
 
10
10
  observe_started_client
11
- update_to_tick 0
11
+ update_to_tick tick: 0
12
12
  end
13
13
 
14
14
  def in_thread?
@@ -6,35 +6,35 @@ N = 100
6
6
  client_class = Tupelo::TimeFuzz::Client
7
7
  Tupelo::TimeFuzz.sleep_max = 0.01
8
8
 
9
- Tupelo.application do |app|
10
- app.child(client_class) do |client|
9
+ Tupelo.application do
10
+ child(client_class) do
11
11
  N.times do
12
- client.transaction do |t|
13
- x, y = t.take [nil, nil]
14
- t.write [x+1, y]
12
+ transaction do
13
+ x, y = take [nil, nil]
14
+ write [x+1, y]
15
15
  end
16
16
  end
17
- client.write ["done"]
17
+ write ["done"]
18
18
  end
19
19
 
20
- app.child(client_class) do |client|
20
+ child(client_class) do
21
21
  N.times do
22
- client.transaction do |t|
23
- x, y = t.take [nil, nil]
24
- t.write [x, y+1]
22
+ transaction do
23
+ x, y = take [nil, nil]
24
+ write [x, y+1]
25
25
  end
26
26
  end
27
- client.write ["done"]
27
+ write ["done"]
28
28
  end
29
29
 
30
- app.local(client_class) do |client|
31
- client.write [0, 0]
30
+ local(client_class) do
31
+ write [0, 0]
32
32
 
33
33
  2.times do
34
- client.take ["done"]
34
+ take ["done"]
35
35
  end
36
36
 
37
- x, y = client.read [nil, nil]
37
+ x, y = read [nil, nil]
38
38
  if x == N and y == N
39
39
  puts "OK"
40
40
  else
@@ -1,24 +1,24 @@
1
1
  require 'tupelo/app'
2
2
 
3
- Tupelo.application do |app|
3
+ Tupelo.application do
4
4
  expected = [[1], [2], [3]]
5
5
 
6
- app.local do |client|
7
- client.write *expected
6
+ local do
7
+ write *expected
8
8
  end
9
9
 
10
- child_pid = app.child do |client|
10
+ child_pid = child do
11
11
  # Test that tuples written before this client started are readable.
12
- a = client.read_all [Integer]
13
- client.write_wait result: a
12
+ a = read_all [Integer]
13
+ write_wait result: a
14
14
  end
15
15
 
16
16
  # Normally we would wait using tuples, but in this case we want more
17
17
  # isolation in the test case, so we wait in terms of the PID.
18
18
  Process.waitpid child_pid
19
19
 
20
- app.local do |client|
21
- h = client.read_all result: Array
20
+ local do
21
+ h = read_all result: Array
22
22
  begin
23
23
  a = h.first["result"]
24
24
  rescue => ex
@@ -164,6 +164,62 @@ class TestOps < Minitest::Test
164
164
  end
165
165
  end
166
166
 
167
+ def test_transaction_take_two
168
+ x = [0]; y = [1]
169
+ c = make_client(1)
170
+
171
+ w_op = c.now {write x, y}
172
+
173
+ c.will do
174
+ transaction do
175
+ [take([nil]), take([nil])]
176
+ end
177
+ end
178
+
179
+ assert_equal [x, y].sort, c.run.sort
180
+ end
181
+
182
+ def test_transaction_take_read
183
+ x = [0]
184
+ c = make_client(1)
185
+
186
+ w_op = c.now {write x}
187
+
188
+ c.will do
189
+ transaction do
190
+ [take(x), read_nowait(x)]
191
+ end
192
+ end
193
+
194
+ assert_equal [x, nil], c.run
195
+ end
196
+
197
+ def test_transaction_write_read
198
+ x = [0]
199
+ c = make_client(1)
200
+
201
+ c.will do
202
+ transaction do
203
+ write(x); read(x)
204
+ end
205
+ end
206
+
207
+ assert_equal x, c.run
208
+ end
209
+
210
+ def test_transaction_write_take
211
+ x = [0]
212
+ c = make_client(1)
213
+
214
+ c.will do
215
+ transaction do
216
+ write(x); take(x)
217
+ end
218
+ end
219
+
220
+ assert_equal x, c.run
221
+ end
222
+
167
223
  def test_transaction_empty
168
224
  transactor = make_client(0)
169
225
 
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.9'
4
+ version: '0.10'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel VanderWerf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-01 00:00:00.000000000 Z
11
+ date: 2013-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: atdo
@@ -83,92 +83,96 @@ files:
83
83
  - lib/tupelo/app/irb-shell.rb
84
84
  - lib/tupelo/app/trace.rb
85
85
  - lib/tupelo/client.rb
86
- - lib/tupelo/app.rb
87
- - lib/tupelo/archiver.rb
88
- - lib/tupelo/client/worker.rb
89
- - lib/tupelo/client/common.rb
90
- - lib/tupelo/client/tuplespace.rb
91
- - lib/tupelo/client/transaction.rb
92
- - lib/tupelo/client/atdo.rb
93
- - lib/tupelo/client/reader.rb
86
+ - lib/tupelo/tuplets/persistent-archiver.rb
94
87
  - lib/tupelo/tuplets/persistent-archiver/worker.rb
95
88
  - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
96
- - lib/tupelo/tuplets/persistent-archiver.rb
89
+ - lib/tupelo/util/boolean.rb
90
+ - lib/tupelo/app.rb
91
+ - lib/tupelo/archiver.rb
97
92
  - lib/tupelo/archiver/persister.rb
98
93
  - lib/tupelo/archiver/worker.rb
99
94
  - lib/tupelo/archiver/tuplespace.rb
100
95
  - lib/tupelo/archiver/persistent-tuplespace.rb
101
- - lib/tupelo/util/boolean.rb
96
+ - lib/tupelo/client/transaction.rb
97
+ - lib/tupelo/client/worker.rb
98
+ - lib/tupelo/client/reader.rb
99
+ - lib/tupelo/client/tuplespace.rb
100
+ - lib/tupelo/client/atdo.rb
101
+ - lib/tupelo/client/common.rb
102
102
  - lib/tupelo/version.rb
103
103
  - bench/pipeline.rb
104
- - bugs/write-read.rb
104
+ - bugs/read-take.rb
105
105
  - bugs/take-write.rb
106
- - example/pubsub.rb
107
- - example/timeout-trans.rb
108
- - example/tiny-client.rb
109
- - example/add.rb
110
- - example/parallel.rb
111
- - example/app-and-tup.rb
112
- - example/small.rb
113
- - example/bounded-retry.rb
114
- - example/map-reduce-v2.rb
115
- - example/zk/lock.rb
116
- - example/concurrent-transactions.rb
117
- - example/cancel.rb
118
- - example/tiny-server.rb
119
- - example/write-wait.rb
120
- - example/tcp.rb
121
106
  - example/timeout.rb
107
+ - example/add-dsl.rb
108
+ - example/remote.rb
109
+ - example/increment.rb
110
+ - example/matching.rb
111
+ - example/dphil.rb
112
+ - example/broker-optimistic.rb
113
+ - example/fail-and-retry.rb
114
+ - example/load-balancer.rb
122
115
  - example/read-in-trans.rb
123
- - example/balance-xfer-retry.rb
124
- - example/lock-mgr-with-queue.rb
125
- - example/hash-tuples.rb
126
- - example/pulse.rb
127
- - example/transaction-logic.rb
128
- - example/remote-map-reduce.rb
129
116
  - example/map-reduce.rb
117
+ - example/bounded-retry.rb
118
+ - example/pregel/remote.rb
119
+ - example/pregel/pagerank.rb
120
+ - example/pregel/pregel.rb
121
+ - example/pregel/distributed.rb
122
+ - example/take-nowait.rb
123
+ - example/boolean-match.rb
130
124
  - example/lease.rb
131
- - example/balance-xfer.rb
132
- - example/add-dsl.rb
133
- - example/lock-mgr.rb
125
+ - example/remote-map-reduce.rb
134
126
  - example/broker-locking.rb
135
- - example/dphil-optimistic.rb
136
- - example/fail-and-retry.rb
137
- - example/dphil-optimistic-v2.rb
138
- - example/broker-optimistic-v2.rb
139
- - example/remote.rb
140
- - example/take-nowait.rb
141
- - example/optimist.rb
127
+ - example/transaction-logic.rb
142
128
  - example/message-bus.rb
129
+ - example/small-simplified.rb
130
+ - example/small.rb
131
+ - example/lock-mgr.rb
132
+ - example/concurrent-transactions.rb
133
+ - example/tcp.rb
134
+ - example/notify.rb
135
+ - example/pulse.rb
136
+ - example/hash-tuples.rb
143
137
  - example/balance-xfer-locking.rb
144
- - example/increment.rb
145
- - example/child-of-child.rb
146
- - example/custom-class.rb
147
- - example/matching.rb
138
+ - example/balance-xfer-retry.rb
148
139
  - example/custom-search.rb
149
- - example/broker-optimistic.rb
150
- - example/notify.rb
151
- - example/small-simplified.rb
152
- - example/broker-queue.rb
153
- - example/async-transaction.rb
154
- - example/boolean-match.rb
155
- - example/load-balancer.rb
140
+ - example/app-and-tup.rb
156
141
  - example/take-many.rb
142
+ - example/dphil-optimistic.rb
143
+ - example/async-transaction.rb
144
+ - example/wait-interrupt.rb
145
+ - example/zk/lock.rb
146
+ - example/subspace.rb
147
+ - example/map-reduce-v2.rb
157
148
  - example/deadlock.rb
158
- - example/dphil.rb
159
- - test/lib/testable-worker.rb
149
+ - example/add.rb
150
+ - example/dphil-optimistic-v2.rb
151
+ - example/parallel.rb
152
+ - example/tiny-client.rb
153
+ - example/lock-mgr-with-queue.rb
154
+ - example/balance-xfer.rb
155
+ - example/cancel.rb
156
+ - example/timeout-trans.rb
157
+ - example/optimist.rb
158
+ - example/tiny-server.rb
159
+ - example/pubsub.rb
160
+ - example/broker-optimistic-v2.rb
161
+ - example/write-wait.rb
162
+ - example/custom-class.rb
163
+ - test/stress/archiver-load.rb
164
+ - test/stress/concurrent-transactions.rb
165
+ - test/system/test-archiver.rb
166
+ - test/lib/mock-client.rb
167
+ - test/lib/time-fuzz.rb
168
+ - test/lib/mock-queue.rb
160
169
  - test/lib/mock-seq.rb
170
+ - test/lib/testable-worker.rb
161
171
  - test/lib/mock-msg.rb
162
- - test/lib/mock-queue.rb
163
- - test/lib/time-fuzz.rb
164
- - test/lib/mock-client.rb
165
- - test/system/test-archiver.rb
166
- - test/unit/test-ops.rb
167
- - test/unit/test-mock-client.rb
168
172
  - test/unit/test-mock-seq.rb
169
173
  - test/unit/test-mock-queue.rb
170
- - test/stress/concurrent-transactions.rb
171
- - test/stress/archiver-load.rb
174
+ - test/unit/test-ops.rb
175
+ - test/unit/test-mock-client.rb
172
176
  - bin/tup
173
177
  - bin/tspy
174
178
  homepage: https://github.com/vjoel/tupelo
@@ -198,13 +202,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
202
  version: '0'
199
203
  requirements: []
200
204
  rubyforge_project:
201
- rubygems_version: 2.1.4
205
+ rubygems_version: 2.1.10
202
206
  signing_key:
203
207
  specification_version: 4
204
208
  summary: Distributed tuplespace
205
209
  test_files:
206
- - test/unit/test-ops.rb
207
- - test/unit/test-mock-client.rb
208
210
  - test/unit/test-mock-seq.rb
209
211
  - test/unit/test-mock-queue.rb
212
+ - test/unit/test-ops.rb
213
+ - test/unit/test-mock-client.rb
210
214
  has_rdoc:
data/bugs/write-read.rb DELETED
@@ -1,15 +0,0 @@
1
- require 'tupelo/app'
2
-
3
- Tupelo.application do |app|
4
- app.local do |client|
5
- begin
6
- val = client.transaction timeout: 0.1 do |t|
7
- t.write [1]
8
- t.read [1] # similarly for take
9
- end
10
- p val # should be [1]
11
- rescue TimeoutError => ex
12
- puts ex
13
- end
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- # more like how you would do it in redis, except that the queue is not stored in
2
- # the central server, so operations on it are not a bottleneck, FWIW
3
-
4
- require 'tupelo/app'
5
-
6
- N_PLAYERS = 10
7
-
8
- Tupelo.application do
9
- N_PLAYERS.times do
10
- # sleep rand / 10 # reduce contention -- could also randomize inserts
11
- child do
12
- me = client_id
13
- write name: me
14
-
15
- you = transaction do
16
- game = read_nowait(
17
- player1: nil,
18
- player2: me)
19
- break game["player1"] if game
20
-
21
- unless take_nowait name: me
22
- raise Tupelo::Client::TransactionFailure
23
- end
24
-
25
- you = take(name: nil)["name"]
26
- write(
27
- player1: me,
28
- player2: you)
29
- you
30
- end
31
-
32
- log "now playing with #{you}"
33
- end
34
- end
35
- end