gizzmo 0.8.3 → 0.9.0
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.
- data/VERSION +1 -1
- data/gizzmo.gemspec +2 -2
- data/lib/gizzard/commands.rb +67 -13
- data/lib/gizzmo.rb +14 -4
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.0
|
data/gizzmo.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gizzmo}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.9.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kyle Maxwell"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-01}
|
13
13
|
s.default_executable = %q{gizzmo}
|
14
14
|
s.description = %q{Gizzmo is a command-line client for managing gizzard clusters.}
|
15
15
|
s.email = %q{kmaxwell@twitter.com}
|
data/lib/gizzard/commands.rb
CHANGED
@@ -176,8 +176,14 @@ module Gizzard
|
|
176
176
|
help! "No shards specified" if shard_ids.empty?
|
177
177
|
shard_ids.each do |shard_id_string|
|
178
178
|
shard_id = ShardId.parse(shard_id_string)
|
179
|
-
|
180
|
-
|
179
|
+
|
180
|
+
upward_links = service.list_upward_links(shard_id)
|
181
|
+
downward_links = service.list_downward_links(shard_id)
|
182
|
+
|
183
|
+
help! "Shard must not be a root or leaf" if upward_links.length == 0 or downward_links.length == 0
|
184
|
+
|
185
|
+
upward_links.each do |uplink|
|
186
|
+
downward_links.each do |downlink|
|
181
187
|
service.add_link(uplink.up_id, downlink.down_id, uplink.weight)
|
182
188
|
new_link = LinkInfo.new(uplink.up_id, downlink.down_id, uplink.weight)
|
183
189
|
service.remove_link(uplink.up_id, uplink.down_id)
|
@@ -211,6 +217,7 @@ module Gizzard
|
|
211
217
|
shard_ids = @argv
|
212
218
|
shard_ids.each do |shard_id_text|
|
213
219
|
shard_id = ShardId.parse(shard_id_text)
|
220
|
+
next if !shard_id
|
214
221
|
service.list_upward_links(shard_id).each do |link_info|
|
215
222
|
output link_info.to_unix
|
216
223
|
end
|
@@ -231,6 +238,30 @@ module Gizzard
|
|
231
238
|
end
|
232
239
|
end
|
233
240
|
|
241
|
+
class MarkbusyCommand < ShardCommand
|
242
|
+
def run
|
243
|
+
shard_ids = @argv
|
244
|
+
shard_ids.each do |shard_id|
|
245
|
+
id = ShardId.parse(shard_id)
|
246
|
+
service.mark_shard_busy(id, 1)
|
247
|
+
shard_info = service.get_shard(id)
|
248
|
+
output shard_info.to_unix
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class MarkunbusyCommand < ShardCommand
|
254
|
+
def run
|
255
|
+
shard_ids = @argv
|
256
|
+
shard_ids.each do |shard_id|
|
257
|
+
id = ShardId.parse(shard_id)
|
258
|
+
service.mark_shard_busy(id, 0)
|
259
|
+
shard_info = service.get_shard(id)
|
260
|
+
output shard_info.to_unix
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
234
265
|
class RepairCommand < ShardCommand
|
235
266
|
def run
|
236
267
|
args = @argv.dup.map{|a| a.split(/\s+/)}.flatten
|
@@ -294,6 +325,7 @@ module Gizzard
|
|
294
325
|
shards = []
|
295
326
|
command_options.write_only_shard ||= "com.twitter.gizzard.shards.WriteOnlyShard"
|
296
327
|
additional_hosts = (command_options.hosts || "").split(/[\s,]+/)
|
328
|
+
exclude_hosts = (command_options.exclude_hosts || "").split(/[\s,]+/)
|
297
329
|
ids = @argv.map{|arg| ShardId.new(*arg.split("/")) rescue nil }.compact
|
298
330
|
by_host = ids.inject({}) do |memo, id|
|
299
331
|
memo[id.hostname] ||= NamedArray.new(id.hostname)
|
@@ -305,10 +337,32 @@ module Gizzard
|
|
305
337
|
by_host[host] ||= NamedArray.new(host)
|
306
338
|
end
|
307
339
|
|
340
|
+
exclude_hosts.each do |host|
|
341
|
+
by_host[host] ||= NamedArray.new(host)
|
342
|
+
end
|
343
|
+
|
308
344
|
sets = by_host.values
|
345
|
+
exclude_sets = exclude_hosts.map{|host| by_host[host]}
|
346
|
+
target_sets = sets - exclude_sets
|
347
|
+
|
348
|
+
exclude_sets.each do |set|
|
349
|
+
while set.length > 0
|
350
|
+
sorted = target_sets.sort_by{|s| s.length}
|
351
|
+
shortest = sorted.first
|
352
|
+
shortest.push set.pop
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
exclude_sets.each do |set|
|
357
|
+
while set.length > 0
|
358
|
+
sorted = target_sets.sort_by{|s| s.length}
|
359
|
+
shortest = sorted.first
|
360
|
+
shortest.push set.pop
|
361
|
+
end
|
362
|
+
end
|
309
363
|
|
310
364
|
begin
|
311
|
-
sorted =
|
365
|
+
sorted = target_sets.sort_by{|s| s.length }
|
312
366
|
longest = sorted.last
|
313
367
|
shortest = sorted.first
|
314
368
|
shortest.push longest.pop
|
@@ -391,27 +445,27 @@ module Gizzard
|
|
391
445
|
|
392
446
|
class ReportCommand < ShardCommand
|
393
447
|
def run
|
394
|
-
|
448
|
+
|
395
449
|
things = @argv.map do |shard|
|
396
450
|
parse(down(ShardId.parse(shard))).join("\n")
|
397
451
|
end
|
398
|
-
|
452
|
+
|
399
453
|
if command_options.flat
|
400
454
|
things.zip(@argv).each do |thing, shard_id|
|
401
455
|
puts "#{sign(thing)}\t#{shard_id}"
|
402
456
|
end
|
403
457
|
else
|
404
458
|
group(things).each do |string, things|
|
405
|
-
puts "=== " + sign(string) + ": #{things.length}" + " ===================="
|
459
|
+
puts "=== " + sign(string) + ": #{things.length}" + " ===================="
|
406
460
|
puts string
|
407
461
|
end
|
408
462
|
end
|
409
463
|
end
|
410
|
-
|
464
|
+
|
411
465
|
def sign(string)
|
412
466
|
::Digest::MD5.hexdigest(string)[0..10]
|
413
467
|
end
|
414
|
-
|
468
|
+
|
415
469
|
def group(arr)
|
416
470
|
arr.inject({}) do |m, e|
|
417
471
|
m[e] ||= []
|
@@ -419,11 +473,11 @@ module Gizzard
|
|
419
473
|
m
|
420
474
|
end.to_a.sort_by{|k, v| v.length}.reverse
|
421
475
|
end
|
422
|
-
|
476
|
+
|
423
477
|
def parse(obj, id = nil, depth = 0, sub = true)
|
424
478
|
case obj
|
425
479
|
when Hash
|
426
|
-
id, prefix = parse(obj.keys.first, id, depth, sub)
|
480
|
+
id, prefix = parse(obj.keys.first, id, depth, sub)
|
427
481
|
[prefix] + parse(obj.values.first, id, depth + 1, sub)
|
428
482
|
when String
|
429
483
|
host, prefix = obj.split("/")
|
@@ -437,7 +491,7 @@ module Gizzard
|
|
437
491
|
end
|
438
492
|
end
|
439
493
|
end
|
440
|
-
|
494
|
+
|
441
495
|
def down(id)
|
442
496
|
vals = service.list_downward_links(id).map do |link|
|
443
497
|
down(link.down_id)
|
@@ -445,8 +499,8 @@ module Gizzard
|
|
445
499
|
{id.to_unix => vals}
|
446
500
|
end
|
447
501
|
end
|
448
|
-
|
449
|
-
class DrillCommand < ReportCommand
|
502
|
+
|
503
|
+
class DrillCommand < ReportCommand
|
450
504
|
def run
|
451
505
|
signature = @argv.shift
|
452
506
|
@argv.map do |shard|
|
data/lib/gizzmo.rb
CHANGED
@@ -85,10 +85,12 @@ subcommands = {
|
|
85
85
|
opts.on("-w", "--write-only=CLASS") do |w|
|
86
86
|
subcommand_options.write_only_shard = w
|
87
87
|
end
|
88
|
-
|
89
88
|
opts.on("-h", "--hosts=list") do |h|
|
90
89
|
subcommand_options.hosts = h
|
91
90
|
end
|
91
|
+
opts.on("-x", "--exclude-hosts=list") do |x|
|
92
|
+
subcommand_options.exclude_hosts = x
|
93
|
+
end
|
92
94
|
end,
|
93
95
|
'repair' => OptionParser.new do |opts|
|
94
96
|
opts.banner = "Usage: #{zero} repair MASTER SLAVE [MASTER SLAVE...]"
|
@@ -102,6 +104,14 @@ subcommands = {
|
|
102
104
|
opts.banner = "Usage: #{zero} subtree SHARD_ID"
|
103
105
|
separators(opts, DOC_STRINGS["subtree"])
|
104
106
|
end,
|
107
|
+
'markbusy' => OptionParser.new do |opts|
|
108
|
+
opts.banner = "Usage: #{zero} markbusy SHARD_ID"
|
109
|
+
separators(opts, DOC_STRINGS["markbusy"])
|
110
|
+
end,
|
111
|
+
'markunbusy' => OptionParser.new do |opts|
|
112
|
+
opts.banner = "Usage: #{zero} markunbusy SHARD_ID"
|
113
|
+
separators(opts, DOC_STRINGS["markunbusy"])
|
114
|
+
end,
|
105
115
|
'hosts' => OptionParser.new do |opts|
|
106
116
|
opts.banner = "Usage: #{zero} hosts"
|
107
117
|
separators(opts, DOC_STRINGS["hosts"])
|
@@ -174,7 +184,7 @@ subcommands = {
|
|
174
184
|
opts.banner = "Usage: #{zero} unlink PARENT_SHARD_ID CHILD_SHARD_ID"
|
175
185
|
separators(opts, DOC_STRINGS["unlink"])
|
176
186
|
end,
|
177
|
-
|
187
|
+
|
178
188
|
'report' => OptionParser.new do |opts|
|
179
189
|
opts.banner = "Usage: #{zero} report [options]"
|
180
190
|
separators(opts, DOC_STRINGS["report"])
|
@@ -182,7 +192,7 @@ subcommands = {
|
|
182
192
|
subcommand_options.flat = true
|
183
193
|
end
|
184
194
|
end,
|
185
|
-
|
195
|
+
|
186
196
|
'lookup' => OptionParser.new do |opts|
|
187
197
|
opts.banner = "Usage: #{zero} lookup [options] TABLE_ID SOURCE"
|
188
198
|
separators(opts, DOC_STRINGS["lookup"])
|
@@ -263,7 +273,7 @@ global = OptionParser.new do |opts|
|
|
263
273
|
opts.on("-r", "--retry=TIMES", "TIMES to retry the command") do |r|
|
264
274
|
global_options.retry = r
|
265
275
|
end
|
266
|
-
|
276
|
+
|
267
277
|
opts.on("-t", "--timeout=SECONDS", "SECONDS to let the command run") do |r|
|
268
278
|
global_options.timeout = r
|
269
279
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 9
|
8
|
+
- 0
|
9
|
+
version: 0.9.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Kyle Maxwell
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-01 00:00:00 -07:00
|
18
18
|
default_executable: gizzmo
|
19
19
|
dependencies: []
|
20
20
|
|