tupelo 0.1
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 +7 -0
- data/COPYING +22 -0
- data/README.md +422 -0
- data/Rakefile +77 -0
- data/bench/pipeline.rb +25 -0
- data/bugs/take-write.rb +19 -0
- data/bugs/write-read.rb +15 -0
- data/example/add.rb +19 -0
- data/example/app-and-tup.rb +30 -0
- data/example/async-transaction.rb +16 -0
- data/example/balance-xfer-locking.rb +50 -0
- data/example/balance-xfer-retry.rb +55 -0
- data/example/balance-xfer.rb +33 -0
- data/example/boolean-match.rb +32 -0
- data/example/bounded-retry.rb +35 -0
- data/example/broker-locking.rb +43 -0
- data/example/broker-optimistic-async.rb +33 -0
- data/example/broker-optimistic.rb +41 -0
- data/example/broker-queue.rb +2 -0
- data/example/cancel.rb +17 -0
- data/example/concurrent-transactions.rb +39 -0
- data/example/custom-class.rb +29 -0
- data/example/custom-search.rb +27 -0
- data/example/fail-and-retry.rb +29 -0
- data/example/hash-tuples.rb +53 -0
- data/example/increment.rb +21 -0
- data/example/lock-mgr-with-queue.rb +75 -0
- data/example/lock-mgr.rb +62 -0
- data/example/map-reduce-v2.rb +96 -0
- data/example/map-reduce.rb +77 -0
- data/example/matching.rb +9 -0
- data/example/notify.rb +35 -0
- data/example/optimist.rb +20 -0
- data/example/pulse.rb +24 -0
- data/example/read-in-trans.rb +56 -0
- data/example/small-simplified.rb +18 -0
- data/example/small.rb +76 -0
- data/example/tcp.rb +35 -0
- data/example/timeout-trans.rb +21 -0
- data/example/timeout.rb +27 -0
- data/example/tiny-client.rb +14 -0
- data/example/tiny-server.rb +12 -0
- data/example/transaction-logic.rb +40 -0
- data/example/write-wait.rb +17 -0
- data/lib/tupelo/app.rb +121 -0
- data/lib/tupelo/archiver/tuplespace.rb +68 -0
- data/lib/tupelo/archiver/worker.rb +87 -0
- data/lib/tupelo/archiver.rb +86 -0
- data/lib/tupelo/client/common.rb +10 -0
- data/lib/tupelo/client/reader.rb +124 -0
- data/lib/tupelo/client/transaction.rb +455 -0
- data/lib/tupelo/client/tuplespace.rb +50 -0
- data/lib/tupelo/client/worker.rb +493 -0
- data/lib/tupelo/client.rb +44 -0
- data/lib/tupelo/version.rb +3 -0
- data/test/lib/mock-client.rb +38 -0
- data/test/lib/mock-msg.rb +47 -0
- data/test/lib/mock-queue.rb +42 -0
- data/test/lib/mock-seq.rb +50 -0
- data/test/lib/testable-worker.rb +24 -0
- data/test/stress/concurrent-transactions.rb +42 -0
- data/test/system/test-archiver.rb +35 -0
- data/test/unit/test-mock-queue.rb +93 -0
- data/test/unit/test-mock-seq.rb +39 -0
- data/test/unit/test-ops.rb +222 -0
- metadata +134 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'tupelo/client/worker'
|
2
|
+
require 'tupelo/client/tuplespace'
|
3
|
+
|
4
|
+
class TestableWorker < Tupelo::Client::Worker
|
5
|
+
def initialize client
|
6
|
+
super
|
7
|
+
|
8
|
+
@cmd_queue = MockQueue.new
|
9
|
+
|
10
|
+
observe_started_client
|
11
|
+
update_to_tick 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def in_thread?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def update
|
19
|
+
begin
|
20
|
+
handle_one_request unless cmd_queue.empty?
|
21
|
+
read_messages_from_seq # doesn't block; reads from seq to queue
|
22
|
+
end until cmd_queue.empty?
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'tupelo/app'
|
2
|
+
|
3
|
+
N = 100
|
4
|
+
|
5
|
+
Tupelo.application do |app|
|
6
|
+
app.child do |client|
|
7
|
+
N.times do
|
8
|
+
client.transaction do |t|
|
9
|
+
x, y = t.take [nil, nil]
|
10
|
+
sleep rand/100
|
11
|
+
t.write [x+1, y]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
client.write ["done"]
|
15
|
+
end
|
16
|
+
|
17
|
+
app.child do |client|
|
18
|
+
N.times do
|
19
|
+
client.transaction do |t|
|
20
|
+
x, y = t.take [nil, nil]
|
21
|
+
sleep rand/100
|
22
|
+
t.write [x, y+1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
client.write ["done"]
|
26
|
+
end
|
27
|
+
|
28
|
+
app.local do |client|
|
29
|
+
client.write [0, 0]
|
30
|
+
|
31
|
+
2.times do
|
32
|
+
client.take ["done"]
|
33
|
+
end
|
34
|
+
|
35
|
+
x, y = client.read [nil, nil]
|
36
|
+
if x == N and y == N
|
37
|
+
puts "OK"
|
38
|
+
else
|
39
|
+
abort "FAIL: x=#{x}, y=#{y}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'tupelo/app'
|
2
|
+
|
3
|
+
Tupelo.application do |app|
|
4
|
+
expected = [[1], [2], [3]]
|
5
|
+
|
6
|
+
app.local do |client|
|
7
|
+
client.write *expected
|
8
|
+
end
|
9
|
+
|
10
|
+
child_pid = app.child do |client|
|
11
|
+
# Test that tuples written before this client started are readable.
|
12
|
+
a = client.read_all [Integer]
|
13
|
+
client.write result: a
|
14
|
+
sleep 0.1
|
15
|
+
end
|
16
|
+
|
17
|
+
# Normally we would wait using tuples, but in this case we want more
|
18
|
+
# isolation in the test case, so we wait in terms of the PID.
|
19
|
+
Process.waitpid child_pid
|
20
|
+
|
21
|
+
app.local do |client|
|
22
|
+
h = client.read_all result: Array
|
23
|
+
begin
|
24
|
+
a = h.first["result"]
|
25
|
+
rescue => ex
|
26
|
+
abort "FAIL: #{ex}, h=#{h.inspect}"
|
27
|
+
end
|
28
|
+
|
29
|
+
if a == expected
|
30
|
+
puts "OK"
|
31
|
+
else
|
32
|
+
abort "FAIL: a=#{a.inspect}, expected=#{expected.inspect}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'mock-queue.rb'
|
4
|
+
|
5
|
+
class TestMockQueueWithPushPopYields < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@q = MockQueue.new yield_on_push: true, yield_on_pop: true
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_push
|
11
|
+
f = Fiber.new do |val|
|
12
|
+
loop do
|
13
|
+
val = @q.push val
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
a = []
|
18
|
+
assert_equal a, @q.entries
|
19
|
+
|
20
|
+
3.times do |i|
|
21
|
+
op, val = f.resume i
|
22
|
+
assert_equal :push, op
|
23
|
+
assert_equal i, val
|
24
|
+
a << i
|
25
|
+
assert_equal a, @q.entries
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_pop
|
30
|
+
a = []
|
31
|
+
f = Fiber.new do
|
32
|
+
loop do
|
33
|
+
a << @q.pop
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
3.times do
|
38
|
+
op = f.resume
|
39
|
+
assert_equal :block, op
|
40
|
+
assert_equal [], a
|
41
|
+
end
|
42
|
+
|
43
|
+
@q.entries.concat (0...10).to_a
|
44
|
+
|
45
|
+
10.times do |i|
|
46
|
+
op, val = f.resume
|
47
|
+
assert_equal :pop, op
|
48
|
+
assert_equal i, val
|
49
|
+
end
|
50
|
+
|
51
|
+
op = f.resume
|
52
|
+
assert_equal :block, op
|
53
|
+
assert_equal a, (0...10).to_a
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class TestMockQueueSimpler < Minitest::Test
|
58
|
+
def setup
|
59
|
+
@q = MockQueue.new
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_push
|
63
|
+
a = []
|
64
|
+
assert_equal a, @q.entries
|
65
|
+
|
66
|
+
3.times do |i|
|
67
|
+
@q.push i
|
68
|
+
a << i
|
69
|
+
assert_equal a, @q.entries
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_pop
|
74
|
+
a = []
|
75
|
+
f = Fiber.new do
|
76
|
+
loop do
|
77
|
+
a << @q.pop
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
3.times do
|
82
|
+
op = f.resume
|
83
|
+
assert_equal :block, op
|
84
|
+
assert_equal [], a
|
85
|
+
end
|
86
|
+
|
87
|
+
@q.entries.concat (0...10).to_a
|
88
|
+
|
89
|
+
op = f.resume
|
90
|
+
assert_equal :block, op
|
91
|
+
assert_equal a, (0...10).to_a
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'mock-seq.rb'
|
4
|
+
require 'mock-msg.rb'
|
5
|
+
|
6
|
+
class TestMockSeq < Minitest::Test
|
7
|
+
def setup
|
8
|
+
@seq = MockSequencer.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_multiple_streams
|
12
|
+
clients = (0..1).map {|i| @seq.stream}
|
13
|
+
|
14
|
+
count = 0
|
15
|
+
expected = []
|
16
|
+
clients.each_with_index do |c, i|
|
17
|
+
(0..2).each do |j|
|
18
|
+
c.write MockMessage[blob: [i,j]]
|
19
|
+
count += 1
|
20
|
+
expected << [count, i,j]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
clients.each_with_index do |c, i|
|
25
|
+
assert_equal expected, c.map {|m| [m.global_tick, *m.blob]}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_alternations_of_reads_and_writes
|
30
|
+
client = @seq.stream
|
31
|
+
client.write MockMessage[blob: 1]
|
32
|
+
client.write MockMessage[blob: 2]
|
33
|
+
assert_equal [1,2], client.map(&:blob)
|
34
|
+
|
35
|
+
client.write MockMessage[blob: "a"]
|
36
|
+
client.write MockMessage[blob: "b"]
|
37
|
+
assert_equal ["a","b"], client.map(&:blob)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
require 'mock-seq.rb'
|
5
|
+
require 'mock-msg.rb'
|
6
|
+
require 'mock-client.rb'
|
7
|
+
require 'testable-worker.rb'
|
8
|
+
|
9
|
+
class TestOps < Minitest::Test
|
10
|
+
attr_reader :seq, :sio, :log
|
11
|
+
|
12
|
+
class MiniFormatter < Logger::Formatter # Based on EasyServe::EasyFormatter
|
13
|
+
Format = "%s: %s: %s\n"
|
14
|
+
|
15
|
+
def call(severity, time, progname, msg)
|
16
|
+
Format % [severity[0..0], progname, msg2str(msg)]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup
|
21
|
+
@seq = MockSequencer.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def make_client cid
|
25
|
+
MockClient.new.tap do |c|
|
26
|
+
c.client_id = cid
|
27
|
+
c.log = Logger.new($stderr).tap do |log|
|
28
|
+
log.level = Logger::WARN
|
29
|
+
log.progname = cid
|
30
|
+
log.formatter = MiniFormatter.new
|
31
|
+
end
|
32
|
+
c.blobber = Marshal
|
33
|
+
c.tuplespace = Tupelo::Client::SimpleTuplespace
|
34
|
+
c.message_class = MockMessage
|
35
|
+
c.seq = seq.stream
|
36
|
+
c.worker = TestableWorker.new(c)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def make_clients n
|
41
|
+
n.times.map {|i| make_client i}
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_one_client
|
45
|
+
client = make_client "one"
|
46
|
+
|
47
|
+
client.update; writer = client.write_nowait [1]
|
48
|
+
client.update; writer.wait
|
49
|
+
client.update; assert_equal 1, writer.global_tick
|
50
|
+
|
51
|
+
reader = Fiber.new do
|
52
|
+
client.read [nil]
|
53
|
+
end
|
54
|
+
|
55
|
+
client.update; reader.resume
|
56
|
+
client.update; assert_equal [1], reader.resume
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_two_clients
|
60
|
+
t = ["c0"]
|
61
|
+
cl = make_clients(2)
|
62
|
+
|
63
|
+
cl[0].write t
|
64
|
+
|
65
|
+
cl.each do |c|
|
66
|
+
reader = Fiber.new { c.read [nil] }; reader.resume
|
67
|
+
c.update; assert_equal t, reader.resume
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_read_existing
|
72
|
+
t = ["foo"]
|
73
|
+
cl = make_clients(2)
|
74
|
+
|
75
|
+
wr = cl[0].write t
|
76
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
77
|
+
|
78
|
+
cl.each do |c|
|
79
|
+
reader = Fiber.new { c.read [nil] }; reader.resume
|
80
|
+
c.update; assert_equal t, reader.resume
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_read_waiting
|
85
|
+
t = ["bar"]
|
86
|
+
cl = make_clients(2)
|
87
|
+
|
88
|
+
reader = Fiber.new { cl[1].read [nil] }; reader.resume
|
89
|
+
|
90
|
+
wr = cl[0].write t
|
91
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
92
|
+
cl[1].update; assert_equal t, reader.resume
|
93
|
+
|
94
|
+
cl.each do |c|
|
95
|
+
reader = Fiber.new { c.read [nil] }; reader.resume
|
96
|
+
c.update; assert_equal t, reader.resume
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_take_existing
|
101
|
+
t = ["foo"]
|
102
|
+
cl = make_clients(2)
|
103
|
+
|
104
|
+
wr = cl[0].write t
|
105
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
106
|
+
|
107
|
+
taker = Fiber.new { cl[1].take [nil] }; taker.resume
|
108
|
+
cl[1].update; taker.resume
|
109
|
+
cl[1].update; assert_equal t, taker.resume
|
110
|
+
cl[0].update
|
111
|
+
|
112
|
+
cl.each do |c|
|
113
|
+
reader = Fiber.new { c.read_all [nil] }; reader.resume
|
114
|
+
c.update; assert_empty reader.resume
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_take_waiting
|
119
|
+
t = ["bar"]
|
120
|
+
cl = make_clients(2)
|
121
|
+
|
122
|
+
taker = Fiber.new { cl[1].take [nil] }; taker.resume
|
123
|
+
cl[1].update; taker.resume
|
124
|
+
cl[1].update; assert_equal :block, taker.resume
|
125
|
+
|
126
|
+
wr = cl[0].write t
|
127
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
128
|
+
cl[1].update; taker.resume
|
129
|
+
cl[1].update; assert_equal t, taker.resume
|
130
|
+
cl[0].update
|
131
|
+
|
132
|
+
cl.each do |c|
|
133
|
+
reader = Fiber.new { c.read_all [nil] }; reader.resume
|
134
|
+
c.update; assert_empty reader.resume
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_transaction_existing
|
139
|
+
w = [1]; t = [2]
|
140
|
+
cl = make_clients(2)
|
141
|
+
|
142
|
+
wr = cl[0].write t
|
143
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
144
|
+
|
145
|
+
trans = Fiber.new do
|
146
|
+
cl[1].transaction do |tr|
|
147
|
+
tr.write w
|
148
|
+
tr.take t
|
149
|
+
end
|
150
|
+
end
|
151
|
+
trans.resume
|
152
|
+
|
153
|
+
cl[1].update; trans.resume
|
154
|
+
cl[1].update; assert_equal t, trans.resume
|
155
|
+
cl[0].update
|
156
|
+
|
157
|
+
cl.each do |c|
|
158
|
+
reader = Fiber.new { c.read_all [nil] }; reader.resume
|
159
|
+
c.update; assert_equal [w], reader.resume
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_transaction_waiting
|
164
|
+
w = [1]; t = [2]
|
165
|
+
cl = make_clients(2)
|
166
|
+
|
167
|
+
trans = Fiber.new do
|
168
|
+
cl[1].transaction do |tr|
|
169
|
+
tr.write w
|
170
|
+
tr.take t
|
171
|
+
end
|
172
|
+
end
|
173
|
+
trans.resume
|
174
|
+
|
175
|
+
wr = cl[0].write t
|
176
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
177
|
+
|
178
|
+
cl[1].update; trans.resume
|
179
|
+
cl[1].update; assert_equal t, trans.resume
|
180
|
+
cl[0].update
|
181
|
+
|
182
|
+
cl.each do |c|
|
183
|
+
reader = Fiber.new { c.read_all [nil] }; reader.resume
|
184
|
+
c.update; assert_equal [w], reader.resume
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_transaction_cancel
|
189
|
+
w = [1]; t = [2]
|
190
|
+
cl = make_clients(2)
|
191
|
+
|
192
|
+
tr = nil
|
193
|
+
trans = Fiber.new do
|
194
|
+
tr = cl[1].transaction
|
195
|
+
tr.write w
|
196
|
+
begin
|
197
|
+
tr.take t
|
198
|
+
tr.commit.wait
|
199
|
+
rescue Tupelo::Client::TransactionAbort
|
200
|
+
Fiber.yield :abort
|
201
|
+
end
|
202
|
+
end
|
203
|
+
cl[1].update; assert_equal :block, trans.resume
|
204
|
+
|
205
|
+
tr.cancel
|
206
|
+
cl[1].update; assert_equal :abort, trans.resume
|
207
|
+
|
208
|
+
wr = cl[0].write t
|
209
|
+
cl[0].update; assert_equal 1, wr.global_tick
|
210
|
+
cl[1].update
|
211
|
+
|
212
|
+
cl.each do |c|
|
213
|
+
reader = Fiber.new { c.read_all [nil] }; reader.resume
|
214
|
+
c.update; assert_equal [t], reader.resume
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
## test Transaction#read
|
219
|
+
## test failure
|
220
|
+
## test pulse
|
221
|
+
## test optimistic
|
222
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tupelo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel VanderWerf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: object-stream
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Distributed tuplespace.
|
28
|
+
email: vjoel@users.sourceforge.net
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.md
|
33
|
+
- COPYING
|
34
|
+
files:
|
35
|
+
- README.md
|
36
|
+
- COPYING
|
37
|
+
- Rakefile
|
38
|
+
- lib/tupelo/client.rb
|
39
|
+
- lib/tupelo/app.rb
|
40
|
+
- lib/tupelo/archiver.rb
|
41
|
+
- lib/tupelo/client/worker.rb
|
42
|
+
- lib/tupelo/client/common.rb
|
43
|
+
- lib/tupelo/client/tuplespace.rb
|
44
|
+
- lib/tupelo/client/transaction.rb
|
45
|
+
- lib/tupelo/client/reader.rb
|
46
|
+
- lib/tupelo/archiver/worker.rb
|
47
|
+
- lib/tupelo/archiver/tuplespace.rb
|
48
|
+
- lib/tupelo/version.rb
|
49
|
+
- bench/pipeline.rb
|
50
|
+
- bugs/write-read.rb
|
51
|
+
- bugs/take-write.rb
|
52
|
+
- example/timeout-trans.rb
|
53
|
+
- example/tiny-client.rb
|
54
|
+
- example/add.rb
|
55
|
+
- example/app-and-tup.rb
|
56
|
+
- example/small.rb
|
57
|
+
- example/bounded-retry.rb
|
58
|
+
- example/map-reduce-v2.rb
|
59
|
+
- example/concurrent-transactions.rb
|
60
|
+
- example/cancel.rb
|
61
|
+
- example/tiny-server.rb
|
62
|
+
- example/write-wait.rb
|
63
|
+
- example/tcp.rb
|
64
|
+
- example/timeout.rb
|
65
|
+
- example/read-in-trans.rb
|
66
|
+
- example/balance-xfer-retry.rb
|
67
|
+
- example/lock-mgr-with-queue.rb
|
68
|
+
- example/hash-tuples.rb
|
69
|
+
- example/pulse.rb
|
70
|
+
- example/transaction-logic.rb
|
71
|
+
- example/map-reduce.rb
|
72
|
+
- example/balance-xfer.rb
|
73
|
+
- example/broker-optimistic-async.rb
|
74
|
+
- example/lock-mgr.rb
|
75
|
+
- example/broker-locking.rb
|
76
|
+
- example/fail-and-retry.rb
|
77
|
+
- example/optimist.rb
|
78
|
+
- example/balance-xfer-locking.rb
|
79
|
+
- example/increment.rb
|
80
|
+
- example/custom-class.rb
|
81
|
+
- example/matching.rb
|
82
|
+
- example/custom-search.rb
|
83
|
+
- example/broker-optimistic.rb
|
84
|
+
- example/notify.rb
|
85
|
+
- example/small-simplified.rb
|
86
|
+
- example/broker-queue.rb
|
87
|
+
- example/async-transaction.rb
|
88
|
+
- example/boolean-match.rb
|
89
|
+
- test/lib/testable-worker.rb
|
90
|
+
- test/lib/mock-seq.rb
|
91
|
+
- test/lib/mock-msg.rb
|
92
|
+
- test/lib/mock-queue.rb
|
93
|
+
- test/lib/mock-client.rb
|
94
|
+
- test/system/test-archiver.rb
|
95
|
+
- test/unit/test-ops.rb
|
96
|
+
- test/unit/test-mock-seq.rb
|
97
|
+
- test/unit/test-mock-queue.rb
|
98
|
+
- test/stress/concurrent-transactions.rb
|
99
|
+
homepage: https://github.com/vjoel/tupelo
|
100
|
+
licenses:
|
101
|
+
- BSD
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options:
|
105
|
+
- --quiet
|
106
|
+
- --line-numbers
|
107
|
+
- --inline-source
|
108
|
+
- --title
|
109
|
+
- tupelo
|
110
|
+
- --main
|
111
|
+
- README.md
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.0.4
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Distributed tuplespace
|
130
|
+
test_files:
|
131
|
+
- test/unit/test-ops.rb
|
132
|
+
- test/unit/test-mock-seq.rb
|
133
|
+
- test/unit/test-mock-queue.rb
|
134
|
+
has_rdoc:
|