gizzmo 0.11.2 → 0.11.3

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.
@@ -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