gizzmo 0.11.2 → 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -90,7 +90,7 @@ module Gizzard
90
90
  end
91
91
  end
92
92
 
93
- NameServerState = T.make_struct(:NameserverState,
93
+ NameServerState = T.make_struct(:NameServerState,
94
94
  T::Field.new(:shards, list(struct(ShardInfo)), 1),
95
95
  T::Field.new(:links, list(struct(LinkInfo)), 2),
96
96
  T::Field.new(:forwardings, list(struct(Forwarding)), 3),
@@ -150,6 +150,7 @@ module Gizzard
150
150
  end
151
151
 
152
152
  class Manager < GizzmoService
153
+ thrift_method :reload_updated_forwardings, void, :throws => exception(GizzardException)
153
154
  thrift_method :reload_config, void, :throws => exception(GizzardException)
154
155
  thrift_method :rebuild_schema, void, :throws => exception(GizzardException)
155
156
 
@@ -179,11 +180,12 @@ module Gizzard
179
180
  thrift_method :get_forwardings, list(struct(Forwarding)), :throws => exception(GizzardException)
180
181
 
181
182
  thrift_method :list_hostnames, list(string), :throws => exception(GizzardException)
183
+ thrift_method :list_tables, list(i32), :throws => exception(GizzardException)
182
184
 
183
185
  thrift_method :mark_shard_busy, void, field(:id, struct(ShardId), 1), field(:busy, i32, 2), :throws => exception(GizzardException)
184
186
  thrift_method :copy_shard, void, field(:source_id, struct(ShardId), 1), field(:destination_id, struct(ShardId), 2), :throws => exception(GizzardException)
185
187
 
186
- thrift_method :dump_nameserver, struct(NameServerState), field(:table_id, i32, 1), :throws => exception(GizzardException)
188
+ thrift_method :dump_nameserver, list(struct(NameServerState)), field(:table_ids, list(i32), 1), :throws => exception(GizzardException)
187
189
 
188
190
 
189
191
  # Job Scheduler Management
@@ -1,3 +1,5 @@
1
+ require "set"
2
+
1
3
  module Gizzard
2
4
  class Transformation
3
5
  require 'gizzard/transformation_op'
@@ -33,7 +35,7 @@ module Gizzard
33
35
 
34
36
  DEFAULT_DEST_WRAPPER = 'WriteOnlyShard'
35
37
 
36
- attr_reader :from, :to
38
+ attr_reader :from, :to, :copy_dest_wrapper
37
39
 
38
40
  def initialize(from_template, to_template, copy_dest_wrapper = nil)
39
41
  copy_dest_wrapper ||= DEFAULT_DEST_WRAPPER
@@ -59,6 +61,27 @@ module Gizzard
59
61
  end
60
62
  end
61
63
 
64
+ def noop?
65
+ from.eql? to
66
+ end
67
+
68
+ def eql?(o)
69
+ o.is_a?(self.class) &&
70
+ from.eql?(o.from) &&
71
+ to.eql?(o.to) &&
72
+ copy_dest_wrapper.eql?(o.copy_dest_wrapper)
73
+ end
74
+
75
+ def <=>(o)
76
+ to_a = lambda {|t| [t.from, t.to, t.copy_dest_wrapper] }
77
+
78
+ to_a.call(self) <=> to_a.call(o)
79
+ end
80
+
81
+ def hash
82
+ from.hash + to.hash + copy_dest_wrapper.hash
83
+ end
84
+
62
85
  def inspect
63
86
  op_inspect = operations.inject({}) do |h, (phase, ops)|
64
87
  h.update phase => ops.map {|job| " #{job.inspect}" }.join("\n")
@@ -198,13 +221,21 @@ module Gizzard
198
221
  end
199
222
 
200
223
  def involved_shards(phase = :copy)
201
- transformation.operations[phase].map do |op|
202
- op.involved_shards(@table_prefix, @translations)
203
- end.flatten.compact.uniq
224
+ @involved_shards ||= {}
225
+ @involved_shards[phase] ||=
226
+ Set.new(transformation.operations[phase].map do |op|
227
+ op.involved_shards(@table_prefix, @translations)
228
+ end.flatten.compact.uniq)
229
+ end
230
+
231
+ def involved_hosts_array(phase = :copy)
232
+ @involved_hosts_array ||= {}
233
+ @involved_hosts_array[phase] ||= involved_shards(phase).map {|s| s.hostname }.uniq
204
234
  end
205
235
 
206
236
  def involved_hosts(phase = :copy)
207
- involved_shards(phase).map {|s| s.hostname }.uniq
237
+ @involved_hosts ||= {}
238
+ @involved_hosts[phase] ||= Set.new(involved_hosts_array(phase))
208
239
  end
209
240
 
210
241
  def inspect
@@ -1,3 +1,5 @@
1
+ require "set"
2
+
1
3
  module Gizzard
2
4
  def self.schedule!(*args)
3
5
  Transformation::Scheduler.new(*args).apply!
@@ -27,9 +29,9 @@ module Gizzard
27
29
  @jobs_in_progress = []
28
30
  @jobs_finished = []
29
31
 
30
- @jobs_pending = transformations.map do |transformation, forwardings_to_shards|
32
+ @jobs_pending = Set.new(transformations.map do |transformation, forwardings_to_shards|
31
33
  transformation.bind(base_name, forwardings_to_shards)
32
- end.flatten
34
+ end.flatten)
33
35
  end
34
36
 
35
37
  # to schedule a job:
@@ -65,26 +67,27 @@ module Gizzard
65
67
  end
66
68
  end
67
69
 
68
- nameserver.reload_config
70
+ nameserver.reload_updated_forwardings
69
71
 
70
72
  log "#{@jobs_finished.length} transformation#{'s' if @jobs_finished.length > 1} applied. Total time elapsed: #{time_elapsed}"
71
73
  end
72
74
 
73
75
  def schedule_jobs(num_to_schedule)
74
76
  to_be_busy_hosts = []
77
+ jobs = []
75
78
 
76
- jobs = (1..num_to_schedule).map do
77
- job = @jobs_pending.find do |j|
78
- (busy_hosts(to_be_busy_hosts) & j.involved_hosts).empty?
79
- end
79
+ @jobs_pending.each do |j|
80
+ if (busy_hosts(to_be_busy_hosts) & j.involved_hosts).empty?
81
+ jobs << j
82
+ to_be_busy_hosts.concat j.involved_hosts_array
80
83
 
81
- if job
82
- to_be_busy_hosts.concat job.involved_hosts
83
- @jobs_pending.delete(job)
84
+ break if jobs.length == num_to_schedule
84
85
  end
86
+ end
87
+
88
+ @jobs_pending.subtract(jobs)
85
89
 
86
- job
87
- end.compact.sort_by {|t| t.forwarding }
90
+ jobs = jobs.sort_by {|t| t.forwarding }
88
91
 
89
92
  unless jobs.empty?
90
93
  log "STARTING:"
@@ -93,7 +96,7 @@ module Gizzard
93
96
  j.prepare!(nameserver)
94
97
  end
95
98
 
96
- nameserver.reload_config
99
+ nameserver.reload_updated_forwardings
97
100
 
98
101
  copy_jobs = jobs.select {|j| j.copy_required? }
99
102
 
@@ -139,9 +142,9 @@ module Gizzard
139
142
  def busy_shards
140
143
  @busy_shards ||=
141
144
  if nameserver.dryrun?
142
- []
145
+ Set.new
143
146
  else
144
- nameserver.get_busy_shards.map {|s| s.id }
147
+ nameserver.get_busy_shards.inject(Set.new) {|set, shard| set.add(shard.id) }
145
148
  end
146
149
  end
147
150
 
@@ -152,7 +155,7 @@ module Gizzard
152
155
  h.update(host => 1) {|_,a,b| a + b }
153
156
  end
154
157
 
155
- copies_count_map.select {|_, count| count >= @copies_per_host }.map {|(host, _)| host }
158
+ copies_count_map.select {|_, count| count >= @copies_per_host }.inject(Set.new) {|set,(host, _)| set.add(host) }
156
159
  end
157
160
 
158
161
  def sleep_with_progress(interval)
@@ -127,24 +127,6 @@ subcommands = {
127
127
  opts.banner = "Usage: #{zero} wrap CLASS_NAME SHARD_ID_TO_WRAP [MORE SHARD_IDS...]"
128
128
  separators(opts, DOC_STRINGS["wrap"])
129
129
  end,
130
- 'rebalance' => OptionParser.new do |opts|
131
- opts.banner = "Usage: #{zero} rebalance"
132
- separators(opts, DOC_STRINGS["rebalance"])
133
-
134
- opts.on("-w", "--write-only=CLASS") do |w|
135
- subcommand_options.write_only_shard = w
136
- end
137
- opts.on("-h", "--shard-hosts=list") do |h|
138
- subcommand_options.hosts = h
139
- end
140
- opts.on("-x", "--exclude-hosts=list") do |x|
141
- subcommand_options.exclude_hosts = x
142
- end
143
- end,
144
- 'repair' => OptionParser.new do |opts|
145
- opts.banner = "Usage: #{zero} repair MASTER SLAVE [MASTER SLAVE...]"
146
- separators(opts, DOC_STRINGS["repair"])
147
- end,
148
130
  'pair' => OptionParser.new do |opts|
149
131
  opts.banner = "Usage: #{zero} pair"
150
132
  separators(opts, DOC_STRINGS["pair"])
@@ -165,6 +147,10 @@ subcommands = {
165
147
  opts.banner = "Usage: #{zero} hosts"
166
148
  separators(opts, DOC_STRINGS["hosts"])
167
149
  end,
150
+ 'tables' => OptionParser.new do |opts|
151
+ opts.banner = "Usage: #{zero} tables"
152
+ separators(opts, DOC_STRINGS["tables"])
153
+ end,
168
154
  'deleteforwarding' => OptionParser.new do |opts|
169
155
  opts.banner = "Usage: #{zero} deleteforwarding TABLE_ID BASE_ID SHARD_ID"
170
156
  separators(opts, DOC_STRINGS["deleteforwarding"])
@@ -308,9 +294,13 @@ subcommands = {
308
294
  opts.banner = "Usage: #{zero} topology [options]"
309
295
  separators(opts, DOC_STRINGS["topology"])
310
296
 
311
- opts.on("--forwardings", "Show topology of forwardings instead of counts") do
297
+ opts.on("--forwardings", "Show topology by forwarding instead of counts") do
312
298
  subcommand_options.forwardings = true
313
299
  end
300
+
301
+ opts.on("--shards", "Show topology by root shard ids instead of counts") do
302
+ subcommand_options.root_shards = true
303
+ end
314
304
  end,
315
305
  'transform-tree' => OptionParser.new do |opts|
316
306
  opts.banner = "Usage: #{zero} transform-tree [options] ROOT_SHARD_ID TEMPLATE"
@@ -323,11 +313,21 @@ subcommands = {
323
313
  end
324
314
  end,
325
315
  'transform' => OptionParser.new do |opts|
326
- opts.banner = "Usage: #{zero} transform [options] FROM_TEMPLATE TO_TEMPLATE"
316
+ opts.banner = "Usage: #{zero} transform [options] FROM_TEMPLATE TO_TEMPLATE ..."
327
317
  separators(opts, DOC_STRINGS['transform'])
328
318
 
329
319
  add_scheduler_opts subcommand_options, opts
330
320
 
321
+ opts.on("-q", "--quiet", "Do not display transformation info (only valid with --force)") do
322
+ subcommand_options.quiet = true
323
+ end
324
+ end,
325
+ 'rebalance' => OptionParser.new do |opts|
326
+ opts.banner = "Usage: #{zero} rebalance [options] WEIGHT TO_TEMPLATE ..."
327
+ separators(opts, DOC_STRINGS["rebalance"])
328
+
329
+ add_scheduler_opts subcommand_options, opts
330
+
331
331
  opts.on("-q", "--quiet", "Do not display transformation info (only valid with --force)") do
332
332
  subcommand_options.quiet = true
333
333
  end
@@ -1,17 +1,13 @@
1
1
  require File.expand_path('../spec_helper.rb', __FILE__)
2
2
 
3
3
  describe "gizzmo (cli)" do
4
- def gizzmo(cmd)
5
- `cd #{ROOT_DIR} && ruby -rubygems -Ilib bin/gizzmo -H localhost -P #{MANAGER_PORT} #{cmd} 2>&1`
6
- end
7
-
8
- def nameserver
9
- @nameserver ||= read_nameserver_db
4
+ def nameserver_db
5
+ @nameserver_db ||= read_nameserver_db
10
6
  end
11
7
 
12
8
  before do
13
9
  reset_nameserver
14
- @nameserver = nil
10
+ @nameserver_db = nil
15
11
  end
16
12
 
17
13
  describe "basic manipulation commands" do
@@ -19,138 +15,145 @@ describe "gizzmo (cli)" do
19
15
  it "creates a single shard" do
20
16
  gizzmo "create TestShard localhost/t0_0"
21
17
 
22
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard")]
18
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard")]
23
19
  end
24
20
 
25
21
  it "creates multiple shards" do
26
22
  gizzmo "create TestShard localhost/t0_0 localhost/t0_1"
27
23
 
28
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
29
- info("localhost", "t0_1", "TestShard")]
24
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
25
+ info("localhost", "t0_1", "TestShard")]
30
26
  end
31
27
 
32
28
  it "honors source and destination types" do
33
29
  gizzmo "create TestShard -s int -d long localhost/t0_0"
34
30
  gizzmo "create TestShard --source-type=int --destination-type=long localhost/t0_1"
35
31
 
36
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard", "int", "long"),
37
- info("localhost", "t0_1", "TestShard", "int", "long")]
32
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard", "int", "long"),
33
+ info("localhost", "t0_1", "TestShard", "int", "long")]
38
34
  end
39
35
  end
40
36
 
41
37
  describe "delete" do
42
38
  it "deletes a shard" do
43
- gizzmo "create TestShard localhost/t0_0"
39
+ ns.create_shard info("localhost", "t0_0", "TestShard")
40
+
44
41
  gizzmo "delete localhost/t0_0"
45
42
 
46
- nameserver[:shards].should == []
43
+ nameserver_db[:shards].should == []
47
44
  end
48
45
  end
49
46
 
50
47
  describe "wrap/unwrap" do
51
48
  before do
52
- gizzmo "create TestShard localhost/t0_0"
53
- gizzmo "create ReplicatingShard localhost/t0_0_replicating"
54
- gizzmo "addlink localhost/t0_0_replicating localhost/t0_0 1"
49
+ ns.create_shard info("localhost", "t0_0", "TestShard")
50
+ ns.create_shard info("localhost", "t0_0_replicating", "ReplicatingShard")
51
+ ns.add_link id("localhost", "t0_0_replicating"), id("localhost", "t0_0"), 1
55
52
 
56
53
  gizzmo "wrap BlockedShard localhost/t0_0"
57
54
  end
58
55
 
59
56
  it "wrap wraps a shard" do
60
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
61
- info("localhost", "t0_0_blocked", "BlockedShard"),
62
- info("localhost", "t0_0_replicating", "ReplicatingShard")]
57
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
58
+ info("localhost", "t0_0_blocked", "BlockedShard"),
59
+ info("localhost", "t0_0_replicating", "ReplicatingShard")]
63
60
 
64
- nameserver[:links].should == [link(id("localhost", "t0_0_blocked"), id("localhost", "t0_0"), 1),
65
- link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0_blocked"), 1)]
61
+ nameserver_db[:links].should == [link(id("localhost", "t0_0_blocked"), id("localhost", "t0_0"), 1),
62
+ link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0_blocked"), 1)]
66
63
  end
67
64
 
68
65
  it "unwrap unwraps a shard" do
69
66
  gizzmo "unwrap localhost/t0_0_blocked"
70
67
 
71
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
72
- info("localhost", "t0_0_replicating", "ReplicatingShard")]
68
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
69
+ info("localhost", "t0_0_replicating", "ReplicatingShard")]
73
70
 
74
- nameserver[:links].should == [link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0"), 1)]
71
+ nameserver_db[:links].should == [link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0"), 1)]
75
72
  end
76
73
 
77
74
  it "unwrap doesn't unwrap a top level shard or a leaf" do
78
75
  gizzmo "unwrap localhost/t0_0"
79
76
  gizzmo "unwrap localhost/t0_0_replicating"
80
77
 
81
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
82
- info("localhost", "t0_0_blocked", "BlockedShard"),
83
- info("localhost", "t0_0_replicating", "ReplicatingShard")]
78
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
79
+ info("localhost", "t0_0_blocked", "BlockedShard"),
80
+ info("localhost", "t0_0_replicating", "ReplicatingShard")]
84
81
 
85
- nameserver[:links].should == [link(id("localhost", "t0_0_blocked"), id("localhost", "t0_0"), 1),
86
- link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0_blocked"), 1)]
82
+ nameserver_db[:links].should == [link(id("localhost", "t0_0_blocked"), id("localhost", "t0_0"), 1),
83
+ link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0_blocked"), 1)]
87
84
  end
88
85
  end
89
86
 
90
87
  describe "markbusy" do
91
88
  it "marks shards busy" do
92
- gizzmo "create TestShard localhost/t0_0"
89
+ ns.create_shard info("localhost", "t0_0", "TestShard")
90
+
93
91
  gizzmo "markbusy localhost/t0_0"
94
92
 
95
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard", "", "", 1)]
93
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard", "", "", 1)]
96
94
  end
97
95
  end
98
96
 
99
97
  describe "markunbusy" do
100
98
  it "marks shards as not busy" do
101
- gizzmo "create TestShard localhost/t0_0"
99
+ ns.create_shard info("localhost", "t0_0", "TestShard")
102
100
  gizzmo "markbusy localhost/t0_0"
101
+
103
102
  gizzmo "markunbusy localhost/t0_0"
104
103
 
105
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard", "", "", 0)]
104
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard", "", "", 0)]
106
105
  end
107
106
  end
108
107
 
109
108
  describe "addforwarding" do
110
109
  it "adds a forwarding" do
111
- gizzmo "create TestShard localhost/t0_0"
110
+ ns.create_shard info("localhost", "t0_0", "TestShard")
111
+
112
112
  gizzmo "addforwarding 0 0 localhost/t0_0"
113
113
 
114
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard")]
115
- nameserver[:forwardings].should == [forwarding(0, 0, id("localhost", "t0_0"))]
114
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard")]
115
+ nameserver_db[:forwardings].should == [forwarding(0, 0, id("localhost", "t0_0"))]
116
116
  end
117
117
  end
118
118
 
119
119
  describe "deleteforwarding" do
120
120
  it "removes a forwarding" do
121
- gizzmo "create TestShard localhost/t0_0"
121
+ ns.create_shard info("localhost", "t0_0", "TestShard")
122
+
122
123
  gizzmo "addforwarding 0 0 localhost/t0_0"
123
124
  gizzmo "deleteforwarding 0 0 localhost/t0_0"
124
125
 
125
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard")]
126
- nameserver[:forwardings].should == []
126
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard")]
127
+ nameserver_db[:forwardings].should == []
127
128
  end
128
129
  end
129
130
 
130
131
  describe "addlink" do
131
132
  it "links two shards" do
132
- gizzmo "create TestShard localhost/t0_0"
133
- gizzmo "create ReplicatingShard localhost/t0_0_replicating"
133
+ ns.create_shard info("localhost", "t0_0", "TestShard")
134
+ ns.create_shard info("localhost", "t0_0_replicating", "ReplicatingShard")
135
+
134
136
  gizzmo "addlink localhost/t0_0_replicating localhost/t0_0 1"
135
137
 
136
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
137
- info("localhost", "t0_0_replicating", "ReplicatingShard")]
138
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
139
+ info("localhost", "t0_0_replicating", "ReplicatingShard")]
138
140
 
139
- nameserver[:links].should == [link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0"), 1)]
141
+ nameserver_db[:links].should == [link(id("localhost", "t0_0_replicating"), id("localhost", "t0_0"), 1)]
140
142
  end
141
143
  end
142
144
 
143
145
  describe "unlink" do
144
146
  it "unlinks two shards" do
145
- gizzmo "create TestShard localhost/t0_0"
146
- gizzmo "create ReplicatingShard localhost/t0_0_replicating"
147
+ ns.create_shard info("localhost", "t0_0", "TestShard")
148
+ ns.create_shard info("localhost", "t0_0_replicating", "ReplicatingShard")
149
+
147
150
  gizzmo "addlink localhost/t0_0_replicating localhost/t0_0 1"
148
151
  gizzmo "unlink localhost/t0_0_replicating localhost/t0_0"
149
152
 
150
- nameserver[:shards].should == [info("localhost", "t0_0", "TestShard"),
151
- info("localhost", "t0_0_replicating", "ReplicatingShard")]
153
+ nameserver_db[:shards].should == [info("localhost", "t0_0", "TestShard"),
154
+ info("localhost", "t0_0_replicating", "ReplicatingShard")]
152
155
 
153
- nameserver[:links].should == []
156
+ nameserver_db[:links].should == []
154
157
  end
155
158
  end
156
159
 
@@ -160,9 +163,9 @@ describe "gizzmo (cli)" do
160
163
  gizzmo "add-host c1:c1host1:7777"
161
164
  gizzmo "add-host c2:c2host1:7777 c2:c2host2:7777"
162
165
 
163
- nameserver[:hosts].should == [ host("c1host1", 7777, "c1"),
164
- host("c2host1", 7777, "c2"),
165
- host("c2host2", 7777, "c2") ]
166
+ nameserver_db[:hosts].should == [host("c1host1", 7777, "c1"),
167
+ host("c2host1", 7777, "c2"),
168
+ host("c2host2", 7777, "c2")]
166
169
  end
167
170
  end
168
171
 
@@ -171,7 +174,7 @@ describe "gizzmo (cli)" do
171
174
  gizzmo "add-host c1:c1host1:7777"
172
175
  gizzmo "remove-host c1:c1host1:7777"
173
176
 
174
- nameserver[:hosts].should == []
177
+ nameserver_db[:hosts].should == []
175
178
  end
176
179
  end
177
180
  end
@@ -179,11 +182,12 @@ describe "gizzmo (cli)" do
179
182
  describe "basic read methods" do
180
183
  before do
181
184
  3.times do |i|
182
- gizzmo "create TestShard -s Int -d Int localhost/t0_#{i}_a 127.0.0.1/t0_#{i}_b"
183
- gizzmo "create ReplicatingShard localhost/t0_#{i}_replicating"
184
- gizzmo "addlink localhost/t0_#{i}_replicating localhost/t0_#{i}_a 1"
185
- gizzmo "addlink localhost/t0_#{i}_replicating 127.0.0.1/t0_#{i}_b 1"
186
- gizzmo "addforwarding 0 #{i} localhost/t0_#{i}_replicating"
185
+ ns.create_shard info("localhost", "t0_#{i}_a", "TestShard", "Int", "Int")
186
+ ns.create_shard info("127.0.0.1", "t0_#{i}_b", "TestShard", "Int", "Int")
187
+ ns.create_shard info("localhost", "t0_#{i}_replicating", "ReplicatingShard")
188
+ ns.add_link id("localhost", "t0_#{i}_replicating"), id("localhost", "t0_#{i}_a"), 1
189
+ ns.add_link id("localhost", "t0_#{i}_replicating"), id("127.0.0.1", "t0_#{i}_b"), 1
190
+ ns.set_forwarding forwarding(0, i, id("localhost", "t0_#{i}_replicating"))
187
191
  end
188
192
  end
189
193
 
@@ -202,6 +206,12 @@ describe "gizzmo (cli)" do
202
206
  end
203
207
  end
204
208
 
209
+ describe "tables" do
210
+ it "prints a list of table ids in the cluster" do
211
+ gizzmo("tables").should == "0\n"
212
+ end
213
+ end
214
+
205
215
  describe "forwardings" do
206
216
  it "lists forwardings and the root of the corresponding shard trees" do
207
217
  gizzmo("forwardings").should == <<-EOF
@@ -264,9 +274,17 @@ c2:c2host2:7777 0
264
274
 
265
275
  it "shows the template for each forwarding" do
266
276
  gizzmo("-T 0 topology --forwardings").should == <<-EOF
267
- 0 ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
268
- 1 ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
269
- 2 ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
277
+ [0] 0 = localhost/t0_0_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
278
+ [0] 1 = localhost/t0_1_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
279
+ [0] 2 = localhost/t0_2_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
280
+ EOF
281
+ end
282
+
283
+ it "shows the template for each root shard" do
284
+ gizzmo("-T 0 topology --shards").should == <<-EOF
285
+ localhost/t0_0_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
286
+ localhost/t0_1_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
287
+ localhost/t0_2_replicating ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1,Int,Int))
270
288
  EOF
271
289
  end
272
290
  end
@@ -276,14 +294,6 @@ c2:c2host2:7777 0
276
294
  it "works"
277
295
  end
278
296
 
279
- describe "rebalance" do
280
- it "works"
281
- end
282
-
283
- describe "repair" do
284
- it "works"
285
- end
286
-
287
297
  describe "reload" do
288
298
  it "works"
289
299
  end
@@ -326,15 +336,15 @@ c2:c2host2:7777 0
326
336
 
327
337
  describe "transform-tree" do
328
338
  it "works" do
329
- gizzmo "create -s Int -d Int TestShard localhost/s_0_001_a"
330
- #gizzmo "create TestShard 127.0.0.1/s_0_001_b"
331
- gizzmo "create ReplicatingShard localhost/s_0_001_replicating"
332
- gizzmo "addlink localhost/s_0_001_replicating localhost/s_0_001_a 1"
333
- #gizzmo "addlink localhost/s_0_001_replicating 127.0.0.1/s_0_001_b 1"
334
- gizzmo "addforwarding 0 1 localhost/s_0_001_replicating"
335
- gizzmo "-f reload"
336
-
337
- gizzmo('-f transform-tree --no-progress --poll-interval=1 "ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))" localhost/s_0_001_replicating').should == <<-EOF
339
+ ns.create_shard info("localhost", "s_0_001_a", "TestShard", "Int", "Int")
340
+ ns.create_shard info("localhost", "s_0_001_replicating", "ReplicatingShard")
341
+ ns.add_link id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1
342
+ ns.set_forwarding forwarding(0, 1, id("localhost", "s_0_001_replicating"))
343
+ ns.reload_config
344
+
345
+ gizzmo('-f transform-tree --no-progress --poll-interval=1 \
346
+ "ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))" \
347
+ localhost/s_0_001_replicating').should == <<-EOF
338
348
  ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1)) :
339
349
  PREPARE
340
350
  create_shard(TestShard/127.0.0.1)
@@ -358,28 +368,82 @@ FINISHING:
358
368
  1 transformation applied. Total time elapsed: 1 second
359
369
  EOF
360
370
 
361
- nameserver[:shards].should == [ info("127.0.0.1", "s_0_0001", "TestShard"),
362
- info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
363
- info("localhost", "s_0_001_replicating", "ReplicatingShard") ]
371
+ nameserver_db[:shards].should == [info("127.0.0.1", "s_0_0001", "TestShard"),
372
+ info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
373
+ info("localhost", "s_0_001_replicating", "ReplicatingShard")]
364
374
 
365
- nameserver[:links].should == [ link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
366
- link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1) ]
375
+ nameserver_db[:links].should == [link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
376
+ link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1)]
367
377
  end
368
378
  end
369
379
 
370
380
  describe "transform" do
371
381
  it "works" do
382
+ 1.upto(2) do |i|
383
+ ns.create_shard info("localhost", "s_0_00#{i}_a", "TestShard", "Int", "Int")
384
+ ns.create_shard info("localhost", "s_0_00#{i}_replicating", "ReplicatingShard")
385
+ ns.add_link id("localhost", "s_0_00#{i}_replicating"), id("localhost", "s_0_00#{i}_a"), 1
386
+ ns.set_forwarding forwarding(0, i, id("localhost", "s_0_00#{i}_replicating"))
387
+ end
388
+ ns.reload_config
389
+
390
+ gizzmo('-f -T0 transform --no-progress --poll-interval=1 \
391
+ "ReplicatingShard -> TestShard(localhost,1,Int,Int)" \
392
+ "ReplicatingShard -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))"').should == <<-EOF
393
+ ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1)) :
394
+ PREPARE
395
+ create_shard(TestShard/127.0.0.1)
396
+ create_shard(WriteOnlyShard)
397
+ add_link(WriteOnlyShard -> TestShard/127.0.0.1)
398
+ add_link(ReplicatingShard -> WriteOnlyShard)
399
+ COPY
400
+ copy_shard(TestShard/127.0.0.1)
401
+ CLEANUP
402
+ add_link(ReplicatingShard -> TestShard/127.0.0.1)
403
+ remove_link(WriteOnlyShard -> TestShard/127.0.0.1)
404
+ remove_link(ReplicatingShard -> WriteOnlyShard)
405
+ delete_shard(WriteOnlyShard)
406
+ Applied to 2 shards:
407
+ [0] 1 = localhost/s_0_001_replicating
408
+ [0] 2 = localhost/s_0_002_replicating
409
+
410
+ STARTING:
411
+ [0] 1 = localhost/s_0_001_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
412
+ [0] 2 = localhost/s_0_002_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
413
+ COPIES:
414
+ localhost/s_0_001_a -> 127.0.0.1/s_0_0001
415
+ localhost/s_0_002_a -> 127.0.0.1/s_0_0002
416
+ FINISHING:
417
+ [0] 1 = localhost/s_0_001_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
418
+ [0] 2 = localhost/s_0_002_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
419
+ 2 transformations applied. Total time elapsed: 1 second
420
+ EOF
421
+
422
+ nameserver_db[:shards].should == [info("127.0.0.1", "s_0_0001", "TestShard"),
423
+ info("127.0.0.1", "s_0_0002", "TestShard"),
424
+ info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
425
+ info("localhost", "s_0_001_replicating", "ReplicatingShard"),
426
+ info("localhost", "s_0_002_a", "TestShard", "Int", "Int"),
427
+ info("localhost", "s_0_002_replicating", "ReplicatingShard")]
428
+
429
+ nameserver_db[:links].should == [link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
430
+ link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1),
431
+ link(id("localhost", "s_0_002_replicating"), id("127.0.0.1", "s_0_0002"), 1),
432
+ link(id("localhost", "s_0_002_replicating"), id("localhost", "s_0_002_a"), 1)]
433
+ end
434
+
435
+ it "works with multiple pages" do
372
436
  1.upto(2) do |i|
373
437
  gizzmo "create TestShard -s Int -d Int localhost/s_0_00#{i}_a"
374
- #gizzmo "create TestShard -s Int -d Int 127.0.0.1/s_0_000#{i}_b"
375
438
  gizzmo "create ReplicatingShard localhost/s_0_00#{i}_replicating"
376
439
  gizzmo "addlink localhost/s_0_00#{i}_replicating localhost/s_0_00#{i}_a 1"
377
- #gizzmo "addlink localhost/s_0_00#{i}_replicating 127.0.0.1/s_0_000#{i}_b 1"
378
440
  gizzmo "addforwarding 0 #{i} localhost/s_0_00#{i}_replicating"
379
441
  end
380
442
  gizzmo "-f reload"
381
443
 
382
- gizzmo('-f -T0 transform --no-progress --poll-interval=1 "ReplicatingShard -> TestShard(localhost,1,Int,Int)" "ReplicatingShard -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))"').should == <<-EOF
444
+ gizzmo('-f -T0 transform --no-progress --poll-interval=1 --max-copies=1 \
445
+ "ReplicatingShard -> TestShard(localhost,1,Int,Int)" \
446
+ "ReplicatingShard -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))"').should == <<-EOF
383
447
  ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1)) :
384
448
  PREPARE
385
449
  create_shard(TestShard/127.0.0.1)
@@ -399,43 +463,46 @@ Applied to 2 shards:
399
463
 
400
464
  STARTING:
401
465
  [0] 1 = localhost/s_0_001_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
402
- [0] 2 = localhost/s_0_002_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
403
466
  COPIES:
404
467
  localhost/s_0_001_a -> 127.0.0.1/s_0_0001
405
- localhost/s_0_002_a -> 127.0.0.1/s_0_0002
406
468
  FINISHING:
407
469
  [0] 1 = localhost/s_0_001_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
470
+ STARTING:
408
471
  [0] 2 = localhost/s_0_002_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
409
- 2 transformations applied. Total time elapsed: 1 second
472
+ COPIES:
473
+ localhost/s_0_002_a -> 127.0.0.1/s_0_0002
474
+ FINISHING:
475
+ [0] 2 = localhost/s_0_002_replicating: ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1))
476
+ 2 transformations applied. Total time elapsed: 2 seconds
410
477
  EOF
411
478
 
412
- nameserver[:shards].should == [ info("127.0.0.1", "s_0_0001", "TestShard"),
413
- info("127.0.0.1", "s_0_0002", "TestShard"),
414
- info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
415
- info("localhost", "s_0_001_replicating", "ReplicatingShard"),
416
- info("localhost", "s_0_002_a", "TestShard", "Int", "Int"),
417
- info("localhost", "s_0_002_replicating", "ReplicatingShard") ]
418
-
419
- nameserver[:links].should == [ link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
420
- link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1),
421
- link(id("localhost", "s_0_002_replicating"), id("127.0.0.1", "s_0_0002"), 1),
422
- link(id("localhost", "s_0_002_replicating"), id("localhost", "s_0_002_a"), 1) ]
479
+ nameserver_db[:shards].should == [info("127.0.0.1", "s_0_0001", "TestShard"),
480
+ info("127.0.0.1", "s_0_0002", "TestShard"),
481
+ info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
482
+ info("localhost", "s_0_001_replicating", "ReplicatingShard"),
483
+ info("localhost", "s_0_002_a", "TestShard", "Int", "Int"),
484
+ info("localhost", "s_0_002_replicating", "ReplicatingShard")]
485
+
486
+ nameserver_db[:links].should == [link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
487
+ link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1),
488
+ link(id("localhost", "s_0_002_replicating"), id("127.0.0.1", "s_0_0002"), 1),
489
+ link(id("localhost", "s_0_002_replicating"), id("localhost", "s_0_002_a"), 1)]
423
490
  end
424
491
 
425
492
  it "works with multiple forwarding tables" do
426
493
  0.upto(1) do |table|
427
494
  1.upto(2) do |i|
428
- gizzmo "create TestShard -s Int -d Int localhost/s_#{table}_00#{i}_a"
429
- #gizzmo "create TestShard -s Int -d Int 127.0.0.1/s_#{table}_000#{i}_b"
430
- gizzmo "create ReplicatingShard localhost/s_#{table}_00#{i}_replicating"
431
- gizzmo "addlink localhost/s_#{table}_00#{i}_replicating localhost/s_#{table}_00#{i}_a 1"
432
- #gizzmo "addlink localhost/s_#{table}_00#{i}_replicating 127.0.0.1/s_#{table}_000#{i}_b 1"
433
- gizzmo "addforwarding #{table} #{i} localhost/s_#{table}_00#{i}_replicating"
495
+ ns.create_shard info("localhost", "s_#{table}_00#{i}_a", "TestShard", "Int", "Int")
496
+ ns.create_shard info("localhost", "s_#{table}_00#{i}_replicating", "ReplicatingShard")
497
+ ns.add_link id("localhost", "s_#{table}_00#{i}_replicating"), id("localhost", "s_#{table}_00#{i}_a"), 1
498
+ ns.set_forwarding forwarding(table, i, id("localhost", "s_#{table}_00#{i}_replicating"))
434
499
  end
435
500
  end
436
- gizzmo "-f reload"
501
+ ns.reload_config
437
502
 
438
- gizzmo('-f -T0,1 transform --no-progress --poll-interval=1 "ReplicatingShard -> TestShard(localhost,1,Int,Int)" "ReplicatingShard -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))"').should == <<-EOF
503
+ gizzmo('-f -T0,1 transform --no-progress --poll-interval=1 \
504
+ "ReplicatingShard -> TestShard(localhost,1,Int,Int)" \
505
+ "ReplicatingShard -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1))"').should == <<-EOF
439
506
  ReplicatingShard(1) -> TestShard(localhost,1,Int,Int) => ReplicatingShard(1) -> (TestShard(localhost,1,Int,Int), TestShard(127.0.0.1,1)) :
440
507
  PREPARE
441
508
  create_shard(TestShard/127.0.0.1)
@@ -473,27 +540,81 @@ FINISHING:
473
540
  4 transformations applied. Total time elapsed: 1 second
474
541
  EOF
475
542
 
476
- nameserver[:shards].should == [ info("127.0.0.1", "s_0_0001", "TestShard"),
477
- info("127.0.0.1", "s_0_0002", "TestShard"),
478
- info("127.0.0.1", "s_1_0001", "TestShard"),
479
- info("127.0.0.1", "s_1_0002", "TestShard"),
480
- info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
481
- info("localhost", "s_0_001_replicating", "ReplicatingShard"),
482
- info("localhost", "s_0_002_a", "TestShard", "Int", "Int"),
483
- info("localhost", "s_0_002_replicating", "ReplicatingShard"),
484
- info("localhost", "s_1_001_a", "TestShard", "Int", "Int"),
485
- info("localhost", "s_1_001_replicating", "ReplicatingShard"),
486
- info("localhost", "s_1_002_a", "TestShard", "Int", "Int"),
487
- info("localhost", "s_1_002_replicating", "ReplicatingShard") ]
488
-
489
- nameserver[:links].should == [ link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
490
- link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1),
491
- link(id("localhost", "s_0_002_replicating"), id("127.0.0.1", "s_0_0002"), 1),
492
- link(id("localhost", "s_0_002_replicating"), id("localhost", "s_0_002_a"), 1),
493
- link(id("localhost", "s_1_001_replicating"), id("127.0.0.1", "s_1_0001"), 1),
494
- link(id("localhost", "s_1_001_replicating"), id("localhost", "s_1_001_a"), 1),
495
- link(id("localhost", "s_1_002_replicating"), id("127.0.0.1", "s_1_0002"), 1),
496
- link(id("localhost", "s_1_002_replicating"), id("localhost", "s_1_002_a"), 1) ]
543
+ nameserver_db[:shards].should == [info("127.0.0.1", "s_0_0001", "TestShard"),
544
+ info("127.0.0.1", "s_0_0002", "TestShard"),
545
+ info("127.0.0.1", "s_1_0001", "TestShard"),
546
+ info("127.0.0.1", "s_1_0002", "TestShard"),
547
+ info("localhost", "s_0_001_a", "TestShard", "Int", "Int"),
548
+ info("localhost", "s_0_001_replicating", "ReplicatingShard"),
549
+ info("localhost", "s_0_002_a", "TestShard", "Int", "Int"),
550
+ info("localhost", "s_0_002_replicating", "ReplicatingShard"),
551
+ info("localhost", "s_1_001_a", "TestShard", "Int", "Int"),
552
+ info("localhost", "s_1_001_replicating", "ReplicatingShard"),
553
+ info("localhost", "s_1_002_a", "TestShard", "Int", "Int"),
554
+ info("localhost", "s_1_002_replicating", "ReplicatingShard")]
555
+
556
+ nameserver_db[:links].should == [link(id("localhost", "s_0_001_replicating"), id("127.0.0.1", "s_0_0001"), 1),
557
+ link(id("localhost", "s_0_001_replicating"), id("localhost", "s_0_001_a"), 1),
558
+ link(id("localhost", "s_0_002_replicating"), id("127.0.0.1", "s_0_0002"), 1),
559
+ link(id("localhost", "s_0_002_replicating"), id("localhost", "s_0_002_a"), 1),
560
+ link(id("localhost", "s_1_001_replicating"), id("127.0.0.1", "s_1_0001"), 1),
561
+ link(id("localhost", "s_1_001_replicating"), id("localhost", "s_1_001_a"), 1),
562
+ link(id("localhost", "s_1_002_replicating"), id("127.0.0.1", "s_1_0002"), 1),
563
+ link(id("localhost", "s_1_002_replicating"), id("localhost", "s_1_002_a"), 1)]
564
+ end
565
+ end
566
+
567
+ describe "rebalance" do
568
+ it "works" do
569
+ 1.upto(8) do |i|
570
+ ns.create_shard info("localhost","s_0_00#{i}_a","TestShard")
571
+ ns.create_shard info("localhost","s_0_00#{i}_replicating","ReplicatingShard")
572
+ ns.add_link id("localhost", "s_0_00#{i}_replicating"), id("localhost", "s_0_00#{i}_a"), 1
573
+ ns.set_forwarding forwarding(0,i,id("localhost", "s_0_00#{i}_replicating"))
574
+ end
575
+ ns.reload_config
576
+
577
+ gizzmo('-f -T0 rebalance --no-progress --poll-interval=1 \
578
+ 1 "ReplicatingShard -> TestShard(127.0.0.1,1)" \
579
+ 1 "ReplicatingShard -> TestShard(localhost,1)"').should match(Regexp.new(Regexp.escape(<<-EOF).gsub("X", "\\d")))
580
+ ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1) :
581
+ PREPARE
582
+ create_shard(TestShard/127.0.0.1)
583
+ create_shard(WriteOnlyShard)
584
+ add_link(WriteOnlyShard -> TestShard/127.0.0.1)
585
+ add_link(ReplicatingShard -> WriteOnlyShard)
586
+ COPY
587
+ copy_shard(TestShard/127.0.0.1)
588
+ CLEANUP
589
+ add_link(ReplicatingShard -> TestShard/127.0.0.1)
590
+ remove_link(ReplicatingShard -> TestShard/localhost)
591
+ remove_link(WriteOnlyShard -> TestShard/127.0.0.1)
592
+ remove_link(ReplicatingShard -> WriteOnlyShard)
593
+ delete_shard(TestShard/localhost)
594
+ delete_shard(WriteOnlyShard)
595
+ Applied to 4 shards:
596
+ [0] X = localhost/s_0_00X_replicating
597
+ [0] X = localhost/s_0_00X_replicating
598
+ [0] X = localhost/s_0_00X_replicating
599
+ [0] X = localhost/s_0_00X_replicating
600
+
601
+ STARTING:
602
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
603
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
604
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
605
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
606
+ COPIES:
607
+ localhost/s_0_00X_a -> 127.0.0.1/s_0_000X
608
+ localhost/s_0_00X_a -> 127.0.0.1/s_0_000X
609
+ localhost/s_0_00X_a -> 127.0.0.1/s_0_000X
610
+ localhost/s_0_00X_a -> 127.0.0.1/s_0_000X
611
+ FINISHING:
612
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
613
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
614
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
615
+ [0] X = localhost/s_0_00X_replicating: ReplicatingShard(1) -> TestShard(localhost,1) => ReplicatingShard(1) -> TestShard(127.0.0.1,1)
616
+ 4 transformations applied. Total time elapsed: 1 second
617
+ EOF
497
618
  end
498
619
  end
499
620
  end