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.
- checksums.yaml +4 -4
- data/README.md +31 -1
- data/bugs/read-take.rb +19 -0
- data/bugs/take-write.rb +7 -7
- data/example/app-and-tup.rb +11 -8
- data/example/async-transaction.rb +7 -7
- data/example/balance-xfer-locking.rb +13 -13
- data/example/balance-xfer-retry.rb +16 -16
- data/example/balance-xfer.rb +9 -9
- data/example/boolean-match.rb +5 -5
- data/example/bounded-retry.rb +9 -9
- data/example/broker-locking.rb +14 -14
- data/example/broker-optimistic.rb +7 -7
- data/example/cancel.rb +7 -7
- data/example/concurrent-transactions.rb +17 -17
- data/example/custom-class.rb +9 -9
- data/example/custom-search.rb +8 -8
- data/example/fail-and-retry.rb +11 -11
- data/example/hash-tuples.rb +12 -10
- data/example/increment.rb +8 -8
- data/example/load-balancer.rb +2 -1
- data/example/lock-mgr-with-queue.rb +18 -18
- data/example/lock-mgr.rb +18 -18
- data/example/map-reduce-v2.rb +11 -11
- data/example/map-reduce.rb +11 -11
- data/example/matching.rb +5 -5
- data/example/message-bus.rb +6 -3
- data/example/notify.rb +17 -17
- data/example/optimist.rb +9 -9
- data/example/parallel.rb +16 -8
- data/example/pregel/distributed.rb +129 -0
- data/example/pregel/pagerank.rb +72 -0
- data/example/pregel/pregel.rb +102 -0
- data/example/pregel/remote.rb +165 -0
- data/example/pulse.rb +10 -10
- data/example/read-in-trans.rb +15 -15
- data/example/subspace.rb +34 -0
- data/example/take-nowait.rb +1 -0
- data/example/tcp.rb +3 -3
- data/example/timeout-trans.rb +5 -5
- data/example/timeout.rb +10 -9
- data/example/tiny-client.rb +5 -5
- data/example/tiny-server.rb +2 -2
- data/example/transaction-logic.rb +16 -16
- data/example/wait-interrupt.rb +38 -0
- data/example/write-wait.rb +11 -11
- data/lib/tupelo/archiver/tuplespace.rb +5 -1
- data/lib/tupelo/archiver/worker.rb +25 -18
- data/lib/tupelo/client/reader.rb +2 -2
- data/lib/tupelo/client/transaction.rb +79 -36
- data/lib/tupelo/client/tuplespace.rb +1 -0
- data/lib/tupelo/client/worker.rb +107 -13
- data/lib/tupelo/client.rb +36 -2
- data/lib/tupelo/version.rb +1 -1
- data/test/lib/mock-client.rb +4 -0
- data/test/lib/testable-worker.rb +1 -1
- data/test/stress/concurrent-transactions.rb +15 -15
- data/test/system/test-archiver.rb +8 -8
- data/test/unit/test-ops.rb +56 -0
- metadata +72 -68
- data/bugs/write-read.rb +0 -15
- data/example/broker-queue.rb +0 -35
- data/example/child-of-child.rb +0 -34
data/lib/tupelo/client/worker.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
|
222
|
-
|
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,
|
259
|
-
|
260
|
-
|
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))
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/tupelo/version.rb
CHANGED
data/test/lib/mock-client.rb
CHANGED
data/test/lib/testable-worker.rb
CHANGED
@@ -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
|
10
|
-
|
9
|
+
Tupelo.application do
|
10
|
+
child(client_class) do
|
11
11
|
N.times do
|
12
|
-
|
13
|
-
x, y =
|
14
|
-
|
12
|
+
transaction do
|
13
|
+
x, y = take [nil, nil]
|
14
|
+
write [x+1, y]
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
write ["done"]
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
child(client_class) do
|
21
21
|
N.times do
|
22
|
-
|
23
|
-
x, y =
|
24
|
-
|
22
|
+
transaction do
|
23
|
+
x, y = take [nil, nil]
|
24
|
+
write [x, y+1]
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
27
|
+
write ["done"]
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
local(client_class) do
|
31
|
+
write [0, 0]
|
32
32
|
|
33
33
|
2.times do
|
34
|
-
|
34
|
+
take ["done"]
|
35
35
|
end
|
36
36
|
|
37
|
-
x, y =
|
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
|
3
|
+
Tupelo.application do
|
4
4
|
expected = [[1], [2], [3]]
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
local do
|
7
|
+
write *expected
|
8
8
|
end
|
9
9
|
|
10
|
-
child_pid =
|
10
|
+
child_pid = child do
|
11
11
|
# Test that tuples written before this client started are readable.
|
12
|
-
a =
|
13
|
-
|
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
|
-
|
21
|
-
h =
|
20
|
+
local do
|
21
|
+
h = read_all result: Array
|
22
22
|
begin
|
23
23
|
a = h.first["result"]
|
24
24
|
rescue => ex
|
data/test/unit/test-ops.rb
CHANGED
@@ -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.
|
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-
|
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/
|
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/
|
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/
|
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/
|
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/
|
132
|
-
- example/add-dsl.rb
|
133
|
-
- example/lock-mgr.rb
|
125
|
+
- example/remote-map-reduce.rb
|
134
126
|
- example/broker-locking.rb
|
135
|
-
- example/
|
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/
|
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/
|
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/
|
159
|
-
-
|
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/
|
171
|
-
- test/
|
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.
|
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
|
data/example/broker-queue.rb
DELETED
@@ -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
|