tupelo 0.12 → 0.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc4bce707ea05097c67e685d20435968d326daaf
4
- data.tar.gz: 02a62f5ed3513d411b0e3bbd4b6d21af08b06c58
3
+ metadata.gz: 8a657d2c56962432faa339d693f6856f409249f6
4
+ data.tar.gz: 64a58b3ab627151aeb2fc8965de21a39c1ebf3f6
5
5
  SHA512:
6
- metadata.gz: 843a155e6e411c6ff9da110b83cfae4c69fa53b06abd0b34b0aa4f469bd97447e58e08091a3009b49d914615547dee9c5f3f3a84e1e0c89481b6184c8f429581
7
- data.tar.gz: 74fd680cd05b27977afc4958eeea19311dcf11120e1d3c2232371e8abda0f275ffc3f9204cb3197412cbb08664c9fc37a789b43c7341a716b00a1f0fc8261fe3
6
+ metadata.gz: 7ea7042705c178a855d4d9ad621c2b65433d0adb4ff7dd75ee855f75d4b53d2bc4301ea91f3491bfaf2847294076a9edffa176290192d004488bdf87caa0b016
7
+ data.tar.gz: 7e371d515db7f86bd95c353fcd5153efd5d1f34ba6edb0c75b7602994309509615f602ba7463729326f3c8d3aa55ba290e67c0e24fac07e917d61e72d668b886
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- **NEWS**: Come hear a talk on Tupelo on December 11 in San Francisco at the [SF Distributed Computing meetup](http://www.meetup.com/San-Francisco-Distributed-Computing). Location is TBD. Abstract: [doc/sfdc.txt](doc/sfdc.txt).
1
+ **NEWS**: Come hear a talk on Tupelo on December 11 in San Francisco at the [SF Distributed Computing meetup](http://www.meetup.com/San-Francisco-Distributed-Computing/events/153886592/). Abstract: [doc/sfdc.txt](doc/sfdc.md).
2
2
 
3
3
  tupelo
4
4
  ==
@@ -93,6 +93,11 @@ Getting started
93
93
 
94
94
  reads all 2-tuples.
95
95
 
96
+ Read tuples in a stream, both existing and as they arrive:
97
+
98
+ read <template> do |tuple| ... end
99
+ read do |tuple| ... end # match any tuple
100
+
96
101
  Take a tuple matching a template:
97
102
 
98
103
  t <template>
@@ -0,0 +1,35 @@
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
@@ -0,0 +1,33 @@
1
+ # Same as chat.rb, but no messages are stored.
2
+
3
+ require 'tupelo/app'
4
+
5
+ svr = "chat-nohistory.yaml"
6
+
7
+ Thread.abort_on_exception = true
8
+
9
+ def display_message msg
10
+ from, time, line = msg.values_at(*%w{from time line})
11
+ time_str = Time.at(time).strftime("%I:%M:%S")
12
+ print "\r\033[2K" # Esc[2K is "Clear entire line"
13
+ puts "#{from}@#{time_str}> #{line}"
14
+ end
15
+
16
+ Tupelo.tcp_application servers_file: svr do
17
+ me = argv.shift
18
+
19
+ local do
20
+ require 'readline'
21
+
22
+ Thread.new do
23
+ read from: nil, line: nil, time: nil do |msg|
24
+ display_message msg
25
+ Readline.refresh_line
26
+ end
27
+ end
28
+
29
+ while line = Readline.readline("#{me}> ", true)
30
+ pulse from: me, line: line, time: Time.now.to_f
31
+ end
32
+ end
33
+ end
data/example/chat/chat.rb CHANGED
@@ -22,7 +22,8 @@ Thread.abort_on_exception = true
22
22
 
23
23
  def display_message msg
24
24
  from, time, line = msg.values_at(*%w{from time line})
25
- time_str = Time.at(time).strftime("%I:%M.%S")
25
+ time_str = Time.at(time).strftime("%I:%M:%S")
26
+ print "\r\033[2K" # Esc[2K is "Clear entire line"
26
27
  puts "#{from}@#{time_str}> #{line}"
27
28
  end
28
29
 
@@ -33,15 +34,9 @@ Tupelo.tcp_application servers_file: svr do
33
34
  require 'readline'
34
35
 
35
36
  Thread.new do
36
- seen_at_start = {}
37
- read_all(from: nil, line: nil, time: nil).
38
- sort_by {|msg| msg["time"]}.
39
- each {|msg| display_message msg; seen_at_start[msg] = true}
40
-
41
37
  read from: nil, line: nil, time: nil do |msg|
42
- next if msg["from"] == me or seen_at_start[msg]
43
- print "\r"; display_message msg
44
- Readline.redisplay ### why not u work?
38
+ display_message msg
39
+ Readline.refresh_line
45
40
  end
46
41
  end
47
42
 
@@ -0,0 +1,34 @@
1
+ require 'tupelo/app'
2
+
3
+ ### need a programmatic way to start up clients
4
+
5
+ Tupelo.application do |app|
6
+
7
+ app.child do ## local still hangs
8
+ 3.times do |i|
9
+ app.child do
10
+ write [i]
11
+ log "wrote #{i}"
12
+ end
13
+ end
14
+
15
+ 3.times do
16
+ log take [nil]
17
+ end
18
+ end
19
+ end
20
+
21
+ __END__
22
+
23
+ this hangs sometimes but not always:
24
+
25
+ tick cid status operation
26
+ A: client 3: wrote 0
27
+ A: client 4: wrote 1
28
+ 1 3 batch write [0]
29
+ 2 4 batch write [1]
30
+ A: client 2: [0]
31
+ 3 2 atomic take [0]
32
+ 4 2 atomic take [1]
33
+ A: client 2: [1]
34
+ A: client 5: wrote 2
data/example/fish01.rb ADDED
@@ -0,0 +1,48 @@
1
+ # This works, but requires a fix-up step.
2
+
3
+ require 'tupelo/app'
4
+
5
+ Tupelo.application do
6
+ 2.times do
7
+ child passive: true do
8
+ loop do
9
+ fish = nil
10
+
11
+ transaction do
12
+ fish, _ = take([String])
13
+ n, _ = take_nowait([Integer, fish])
14
+ if n
15
+ write [n + 1, fish]
16
+ else
17
+ write [1, fish] # another process might also write this, so ...
18
+ end
19
+ end
20
+ ### what if both processes die here?
21
+ transaction do # ... fix up the two tuples.
22
+ n1, _ = take_nowait [Integer, fish]; abort unless n1
23
+ n2, _ = take_nowait [Integer, fish]; abort unless n2
24
+ #log "fixing: #{[n1 + n2, fish]}"
25
+ write [n1 + n2, fish]
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ local do
32
+ seed = 3
33
+ srand seed
34
+ log "seed = #{seed}"
35
+
36
+ fishes = %w{ trout marlin char salmon }
37
+
38
+ a = fishes * 10
39
+ a.shuffle!
40
+ a.each do |fish|
41
+ write [fish]
42
+ end
43
+
44
+ fishes.each do |fish|
45
+ log take [10, fish]
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ #
2
+ # Minor optimization:
3
+
4
+ class KeyMatcher
5
+ def initialize i, n
6
+ @i = i
7
+ @n = n
8
+ end
9
+
10
+ def === id
11
+ id % @n == @i
12
+ end
13
+ end
14
+
15
+ vertex = take id: v_id_matcher, step: step, rank: nil, active: true
@@ -0,0 +1,106 @@
1
+ ## TODO
2
+ ##
3
+ ## scaling params
4
+
5
+ require 'tupelo/app'
6
+
7
+ ab_tag = "my address book"
8
+ ab_sort_field = 1
9
+ ab_val_field = 2
10
+ cmd_tag = "#{ab_tag} commands"
11
+ resp_tag = "#{ab_tag} responses"
12
+
13
+ Tupelo.application do
14
+ local do
15
+ use_subspaces!
16
+
17
+ # Subspace for tuples belonging to the addr book.
18
+ define_subspace(
19
+ tag: ab_tag,
20
+ template: [
21
+ {value: ab_tag},
22
+ {type: "string"}, # name <-- ab_sort_field references this field
23
+ nil # address; can be any object <-- ab_val_field
24
+ ]
25
+ )
26
+
27
+ # Subspace for commands for fetch and delete.
28
+ # We can't use #read and #take because then the requesting client
29
+ # would have to subscribe to the ab_tag subspace.
30
+ define_subspace(
31
+ tag: cmd_tag,
32
+ template: [
33
+ {value: cmd_tag},
34
+ {type: "string"}, # cmd name
35
+ {type: "list"} # arguments
36
+ ]
37
+ )
38
+
39
+ # Subspace for responses to commands. Identify the command this is in
40
+ # response to by copying it (alternately, could use ids).
41
+ define_subspace(
42
+ tag: resp_tag,
43
+ template: [
44
+ {value: resp_tag},
45
+ {type: "string"}, # cmd name
46
+ {type: "list"}, # arguments
47
+ nil # result of query -- type depends on command
48
+ ]
49
+ )
50
+ end
51
+
52
+ ## Could set N_SORTED_SET_SPACE > 1, but lookups are so fast it would
53
+ ## just lead to contention and redundant computation. Redundancy is useful
54
+ ## though.
55
+
56
+ # Inserts are just writes, which are handled by Worker and SortedSetSpace,
57
+ # so this child's app loop only needs to handle special commands: fetch and
58
+ # delete, which are delegated to the SortedSetSpace.
59
+ child tuplespace: [SortedSetSpace, ab_tag, ab_sort_field, ab_val_field],
60
+ subscribe: [ab_tag, cmd_tag], passive: true do
61
+ loop do
62
+ transaction do
63
+ _, cmd, args = take(subspace cmd_tag)
64
+
65
+ case cmd
66
+ when "delete"
67
+ args.each do |name|
68
+ take [ab_tag, name, nil]
69
+ end
70
+
71
+ when "fetch"
72
+ name = args[0]
73
+ _, _, addr = read [ab_tag, name, nil]
74
+ write [resp_tag, name, args, addr]
75
+
76
+ when "next", "prev"
77
+ name = args[0]
78
+ _, name2, addr = read SortedSetTemplate[ab_tag, cmd, name]
79
+ write [resp_tag, name, args, name2, addr]
80
+
81
+ when "first", "last"
82
+ _, name, addr = read SortedSetTemplate[ab_tag, cmd]
83
+ write [resp_tag, name, args, name, addr]
84
+
85
+ else # maybe write an error message in a tuple
86
+ log.error "bad command: #{cmd}"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ child subscribe: resp_tag do
93
+ # write some ab entries
94
+ write [ab_tag, "McFirst, Firsty", "123 W. Crescent Terrace"]
95
+ write [ab_tag, "Secondismus, Deuce", "456 S. West Way"]
96
+
97
+ # make some queries
98
+ write [cmd_tag, "first", []]
99
+ *, name, addr = take [resp_tag, "first", [], nil, nil]
100
+ log "first entry: #{name} => #{addr}"
101
+
102
+ write [cmd_tag, "next", [name]]
103
+ *, name, addr = take [resp_tag, "next", [name], nil, nil]
104
+ log "next entry: #{name} => #{addr}"
105
+ end
106
+ end
@@ -0,0 +1,18 @@
1
+ require 'tupelo/app'
2
+
3
+ Tupelo.application do
4
+ local do
5
+ use_subspaces!
6
+
7
+ define_subspace(
8
+ tag: "address books",
9
+ template: {
10
+ book: {type: "string"},
11
+ name: {type: "string"},
12
+ address: nil
13
+ }
14
+ )
15
+
16
+ define_subspace
17
+ end
18
+ end
@@ -0,0 +1,130 @@
1
+ require 'rbtree'
2
+
3
+ class SortedSetTemplate
4
+ class << self
5
+ alias [] new
6
+ end
7
+
8
+ # cmd can be "next", "prev", "first", "last"
9
+ # for next/prev, args is ["name"]
10
+ # for first/last, args is empty
11
+ def initialize tag, cmd, *args
12
+ @tag = tag
13
+ @cmd = cmd
14
+ @args = args
15
+ end
16
+
17
+ def === other
18
+ raise ### should not need this?
19
+ end
20
+
21
+ def find_in rbtree
22
+ case @cmd
23
+ when "first"
24
+ rbtree.first
25
+ ###
26
+ end
27
+ end
28
+
29
+ # A tuple store (in-memory) that is optimized for (key_string, object) pairs.
30
+ # The object may be any serializable object (built up from numbers, booleans,
31
+ # nil, strings, hashes and arrays).
32
+ #
33
+ # Unlike in a key-value store, a given key_string may occur more than once.
34
+ # It is up to the application to decide whether to enforce key uniqueness or
35
+ # not (for example, by taking (k,...) before writing (k,v).
36
+ #
37
+ # This store should be used only by clients that subscribe to a subspace
38
+ # that can be represented as pairs. (See memo2.rb.)
39
+ #
40
+ # This store also manages meta tuples, which it keeps in an array, just like
41
+ # the default Tuplespace class does.
42
+ class SortedSetSpace
43
+ include Enumerable
44
+
45
+ attr_reader :tag, :hash, :metas
46
+
47
+ def initialize tag
48
+ @tag = tag
49
+ clear
50
+ end
51
+
52
+ def clear
53
+ @hash = Hash.new {|h,k| h[k] = []}
54
+ # It's up to the application to enforce that these arrays have size <=1.
55
+ @metas = []
56
+ # We are automatically subscribed to tupelo metadata (subspace defs), so
57
+ # we need to keep them somewhere.
58
+ end
59
+
60
+ def each
61
+ hash.each do |k, vs|
62
+ vs.each do |v|
63
+ yield tag, k, v
64
+ end
65
+ end
66
+ metas.each do |tuple|
67
+ yield tuple
68
+ end
69
+ end
70
+
71
+ def insert tuple
72
+ if tuple.kind_of? Array
73
+ # and tuple.size == 3 and tuple[0] == tag and tuple[1].kind_of? String
74
+ # This is redundant, because of subscribe.
75
+ t, k, v = tuple
76
+ hash[k] << v
77
+
78
+ else
79
+ metas << tuple
80
+ end
81
+ end
82
+
83
+ def delete_once tuple
84
+ if tuple.kind_of? Array
85
+ # and tuple.size == 3 and tuple[0] == tag and tuple[1].kind_of? String
86
+ # This is redundant, because of subscribe.
87
+ t, k, v = tuple
88
+ if hash.key?(k) and hash[k].include? v
89
+ hash[k].delete v
90
+ hash.delete k if hash[k].empty?
91
+ true
92
+ else
93
+ false
94
+ end
95
+
96
+ else
97
+ if i=metas.index(tuple)
98
+ delete_at i
99
+ end
100
+ end
101
+ end
102
+
103
+ def transaction inserts: [], deletes: [], tick: nil
104
+ deletes.each do |tuple|
105
+ delete_once tuple or raise "bug"
106
+ end
107
+
108
+ inserts.each do |tuple|
109
+ insert tuple.freeze ## should be deep_freeze
110
+ end
111
+ end
112
+
113
+ def find_distinct_matches_for templates
114
+ templates.inject([]) do |tuples, template|
115
+ tuples << find_match_for(template, distinct_from: tuples)
116
+ end
117
+ end
118
+
119
+ def find_match_for template, distinct_from: []
120
+ case template
121
+ when SortedSetTemplate
122
+ template.find_in rbtree, distinct_from: distinct_from ###
123
+ else
124
+ # fall back to linear search
125
+ find do |tuple|
126
+ template === tuple and not distinct_from.any? {|t| t.equal? tuple}
127
+ end
128
+ end
129
+ end
130
+ end
@@ -3,10 +3,14 @@ require 'tupelo/client/common'
3
3
  class Tupelo::Client
4
4
  # Include into class that defines #worker and #log.
5
5
  module Api
6
- # If block given, yield matching tuple to the block if one is found
7
- # locally and then yield each new tuple as it arrives.
8
- # Otherwise, return one matching tuple, blocking if necessary.
9
- def read_wait template
6
+ # If no block given, return one matching tuple, blocking if necessary.
7
+ # If block given, yield each matching tuple that is found
8
+ # locally and then yield each new match as it is written to the space.
9
+ # Guaranteed not to miss tuples, even if they arrive and are immediately
10
+ # taken. (Note that simply doing read(template) in a loop would not
11
+ # have this guarantee.)
12
+ # The template defaults to Object, which matches any tuple.
13
+ def read_wait template = Object
10
14
  waiter = Waiter.new(worker.make_template(template), self, !block_given?)
11
15
  worker << waiter
12
16
  if block_given?
@@ -23,13 +27,16 @@ class Tupelo::Client
23
27
  end
24
28
  alias read read_wait
25
29
 
26
- def read_nowait template
30
+ # The template defaults to Object, which matches any tuple.
31
+ def read_nowait template = Object
27
32
  matcher = Matcher.new(worker.make_template(template), self)
28
33
  worker << matcher
29
34
  matcher.wait
30
35
  end
31
36
 
32
- # By default, reads *everything*.
37
+ # Returns all matching tuples currently in the space. The template defaults
38
+ # to Object, which matches any tuple. Does not wait for more tuples to
39
+ # arrive.
33
40
  def read_all template = Object
34
41
  matcher = Matcher.new(worker.make_template(template), self, :all => true)
35
42
  worker << matcher
@@ -507,13 +507,15 @@ class Tupelo::Client
507
507
  end
508
508
 
509
509
  def handle_waiter waiter
510
- tuple = tuplespace.find_match_for waiter.template
511
- if tuple
512
- once = waiter.peek tuple
513
- unless once
510
+ if waiter.once
511
+ tuple = tuplespace.find_match_for waiter.template
512
+ if tuple
513
+ waiter.peek tuple
514
+ else
514
515
  read_waiters << waiter
515
516
  end
516
517
  else
518
+ tuplespace.each {|tuple| waiter.gloms tuple}
517
519
  read_waiters << waiter
518
520
  end
519
521
  end
@@ -1,3 +1,3 @@
1
1
  module Tupelo
2
- VERSION = "0.12"
2
+ VERSION = "0.13"
3
3
  end
@@ -86,6 +86,30 @@ class TestOps < Minitest::Test
86
86
  end
87
87
  end
88
88
 
89
+ def test_read_stream
90
+ writer, reader = make_clients(2)
91
+ a = []
92
+ n = 10; k = 3
93
+
94
+ (0...k).each do |i|
95
+ writer.now {write [i]}
96
+ end
97
+
98
+ reader.will {read([nil]){|t| a << t}}
99
+
100
+ (0...k).each do |i|
101
+ reader.run_until_blocked
102
+ assert_equal [i], a[i]
103
+ end
104
+
105
+ assert_equal [0], a[0]
106
+ (k...n).each do |i|
107
+ writer.now {write [i]}
108
+ reader.run_until_blocked
109
+ assert_equal [i], a[i]
110
+ end
111
+ end
112
+
89
113
  def test_take_existing
90
114
  t = ["foo"]
91
115
  cl = 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.12'
4
+ version: '0.13'
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-12-03 00:00:00.000000000 Z
11
+ date: 2013-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: atdo
@@ -84,111 +84,119 @@ files:
84
84
  - lib/tupelo/app/trace.rb
85
85
  - lib/tupelo/app/builder.rb
86
86
  - lib/tupelo/client.rb
87
- - lib/tupelo/tuplets/persistent-archiver.rb
88
- - lib/tupelo/tuplets/persistent-archiver/worker.rb
89
- - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
90
- - lib/tupelo/util/boolean.rb
91
87
  - lib/tupelo/app.rb
92
88
  - lib/tupelo/archiver.rb
89
+ - lib/tupelo/client/worker.rb
90
+ - lib/tupelo/client/common.rb
91
+ - lib/tupelo/client/tuplespace.rb
92
+ - lib/tupelo/client/transaction.rb
93
+ - lib/tupelo/client/atdo.rb
94
+ - lib/tupelo/client/reader.rb
95
+ - lib/tupelo/tuplets/persistent-archiver/worker.rb
96
+ - lib/tupelo/tuplets/persistent-archiver/tuplespace.rb
97
+ - lib/tupelo/tuplets/persistent-archiver.rb
93
98
  - lib/tupelo/archiver/persister.rb
94
99
  - lib/tupelo/archiver/worker.rb
95
100
  - lib/tupelo/archiver/tuplespace.rb
96
101
  - lib/tupelo/archiver/persistent-tuplespace.rb
97
- - lib/tupelo/client/transaction.rb
98
- - lib/tupelo/client/worker.rb
99
- - lib/tupelo/client/reader.rb
100
- - lib/tupelo/client/tuplespace.rb
101
- - lib/tupelo/client/atdo.rb
102
- - lib/tupelo/client/common.rb
102
+ - lib/tupelo/util/boolean.rb
103
103
  - lib/tupelo/version.rb
104
104
  - bench/pipeline.rb
105
105
  - bugs/read-take.rb
106
106
  - bugs/take-write.rb
107
+ - example/pubsub.rb
108
+ - example/timeout-trans.rb
109
+ - example/fish01.rb
110
+ - example/tiny-client.rb
111
+ - example/add.rb
112
+ - example/parallel.rb
113
+ - example/socket-broker.rb
114
+ - example/multi-tier/memo2.rb
115
+ - example/multi-tier/drb.rb
116
+ - example/multi-tier/memo.rb
117
+ - example/multi-tier/kvspace.rb
118
+ - example/multi-tier/http.rb
119
+ - example/multi-tier/multi-sinatras.rb
120
+ - example/app-and-tup.rb
121
+ - example/small.rb
122
+ - example/bounded-retry.rb
123
+ - example/fish.rb
124
+ - example/zk/lock.rb
125
+ - example/concurrent-transactions.rb
126
+ - example/cancel.rb
127
+ - example/map-reduce/map-reduce-v2.rb
128
+ - example/map-reduce/remote-map-reduce.rb
129
+ - example/map-reduce/map-reduce.rb
130
+ - example/tiny-server.rb
131
+ - example/write-wait.rb
132
+ - example/tcp.rb
107
133
  - example/timeout.rb
134
+ - example/read-in-trans.rb
135
+ - example/subspaces/simple.rb
136
+ - example/subspaces/pubsub.rb
137
+ - example/subspaces/addr-book-v1.rb
138
+ - example/subspaces/addr-book-v2.rb
139
+ - example/subspaces/shop/shop-v2.rb
140
+ - example/subspaces/shop/shop-v1.rb
141
+ - example/subspaces/sorted-set-space.rb
142
+ - example/balance-xfer-retry.rb
143
+ - example/take-nowait-caution.rb
144
+ - example/lock-mgr-with-queue.rb
145
+ - example/hash-tuples.rb
146
+ - example/pulse.rb
147
+ - example/transaction-logic.rb
148
+ - example/lease.rb
149
+ - example/chat/chat.rb
150
+ - example/chat/chat-nohistory.rb
151
+ - example/balance-xfer.rb
108
152
  - example/add-dsl.rb
109
- - example/remote.rb
110
- - example/increment.rb
111
- - example/matching.rb
112
- - example/dphil.rb
113
- - example/broker-optimistic.rb
153
+ - example/lock-mgr.rb
154
+ - example/broker-locking.rb
155
+ - example/dphil-optimistic.rb
114
156
  - example/fail-and-retry.rb
115
- - example/load-balancer.rb
116
- - example/read-in-trans.rb
117
- - example/bounded-retry.rb
118
- - example/pregel/remote.rb
119
- - example/pregel/pagerank.rb
157
+ - example/fish0.rb
120
158
  - example/pregel/pregel.rb
121
159
  - example/pregel/distributed.rb
160
+ - example/pregel/pagerank.rb
122
161
  - example/pregel/update.rb
162
+ - example/pregel/remote.rb
163
+ - example/pregel/dist-opt.rb
164
+ - example/dphil-optimistic-v2.rb
165
+ - example/broker-optimistic-v2.rb
166
+ - example/remote.rb
123
167
  - example/take-nowait.rb
124
- - example/boolean-match.rb
125
- - example/lease.rb
126
- - example/broker-locking.rb
127
- - example/transaction-logic.rb
168
+ - example/wait-interrupt.rb
169
+ - example/optimist.rb
128
170
  - example/message-bus.rb
129
- - example/small-simplified.rb
130
- - example/small.rb
131
- - example/lock-mgr.rb
132
- - example/take-nowait-caution.rb
133
- - example/concurrent-transactions.rb
134
- - example/tcp.rb
135
- - example/notify.rb
136
- - example/pulse.rb
137
- - example/chat/chat.rb
138
- - example/hash-tuples.rb
139
171
  - example/balance-xfer-locking.rb
140
- - example/balance-xfer-retry.rb
172
+ - example/increment.rb
173
+ - example/child-of-child.rb
174
+ - example/custom-class.rb
175
+ - example/matching.rb
141
176
  - example/custom-search.rb
142
- - example/app-and-tup.rb
143
- - example/multi-tier/memo2.rb
144
- - example/multi-tier/http.rb
145
- - example/multi-tier/multi-sinatras.rb
146
- - example/multi-tier/kvspace.rb
147
- - example/multi-tier/memo.rb
148
- - example/multi-tier/drb.rb
149
- - example/take-many.rb
150
- - example/subspaces/simple.rb
151
- - example/subspaces/shop/shop-v2.rb
152
- - example/subspaces/shop/shop-v1.rb
153
- - example/subspaces/pubsub.rb
154
- - example/dphil-optimistic.rb
177
+ - example/broker-optimistic.rb
178
+ - example/notify.rb
179
+ - example/small-simplified.rb
180
+ - example/broker-queue.rb
155
181
  - example/async-transaction.rb
156
- - example/wait-interrupt.rb
157
- - example/fish0.rb
158
- - example/zk/lock.rb
182
+ - example/boolean-match.rb
183
+ - example/load-balancer.rb
184
+ - example/take-many.rb
159
185
  - example/deadlock.rb
160
- - example/fish.rb
161
- - example/add.rb
162
- - example/dphil-optimistic-v2.rb
163
- - example/parallel.rb
164
- - example/tiny-client.rb
165
- - example/map-reduce/map-reduce.rb
166
- - example/map-reduce/remote-map-reduce.rb
167
- - example/map-reduce/map-reduce-v2.rb
168
- - example/lock-mgr-with-queue.rb
169
- - example/balance-xfer.rb
170
- - example/cancel.rb
171
- - example/socket-broker.rb
172
- - example/timeout-trans.rb
173
- - example/optimist.rb
174
- - example/tiny-server.rb
175
- - example/pubsub.rb
176
- - example/broker-optimistic-v2.rb
177
- - example/write-wait.rb
178
- - example/custom-class.rb
179
- - test/stress/archiver-load.rb
180
- - test/stress/concurrent-transactions.rb
181
- - test/system/test-archiver.rb
182
- - test/lib/mock-client.rb
183
- - test/lib/time-fuzz.rb
184
- - test/lib/mock-queue.rb
185
- - test/lib/mock-seq.rb
186
+ - example/dphil.rb
186
187
  - test/lib/testable-worker.rb
188
+ - test/lib/mock-seq.rb
187
189
  - test/lib/mock-msg.rb
188
- - test/unit/test-mock-seq.rb
189
- - test/unit/test-mock-queue.rb
190
+ - test/lib/mock-queue.rb
191
+ - test/lib/time-fuzz.rb
192
+ - test/lib/mock-client.rb
193
+ - test/system/test-archiver.rb
190
194
  - test/unit/test-ops.rb
191
195
  - test/unit/test-mock-client.rb
196
+ - test/unit/test-mock-seq.rb
197
+ - test/unit/test-mock-queue.rb
198
+ - test/stress/concurrent-transactions.rb
199
+ - test/stress/archiver-load.rb
192
200
  - bin/tup
193
201
  - bin/tspy
194
202
  homepage: https://github.com/vjoel/tupelo
@@ -223,8 +231,8 @@ signing_key:
223
231
  specification_version: 4
224
232
  summary: Distributed tuplespace
225
233
  test_files:
226
- - test/unit/test-mock-seq.rb
227
- - test/unit/test-mock-queue.rb
228
234
  - test/unit/test-ops.rb
229
235
  - test/unit/test-mock-client.rb
236
+ - test/unit/test-mock-seq.rb
237
+ - test/unit/test-mock-queue.rb
230
238
  has_rdoc: