tupelo 0.9 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
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