gizzmo 0.7.0 → 0.7.4

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 CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.7.4
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.7.0"
8
+ s.version = "0.7.4"
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-08-25}
12
+ s.date = %q{2010-10-04}
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}
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  "gizzmo.gemspec",
30
30
  "lib/gizzard.rb",
31
31
  "lib/gizzard/commands.rb",
32
+ "lib/gizzard/digest.rb",
32
33
  "lib/gizzard/thrift.rb",
33
34
  "lib/gizzmo.rb",
34
35
  "lib/vendor/thrift_client/simple.rb",
data/lib/gizzard.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  $: << File.dirname(__FILE__)
2
2
  module Gizzard; end
3
3
  require "gizzard/thrift"
4
- require "gizzard/commands"
4
+ require "gizzard/commands"
5
+ require "gizzard/digest"
@@ -5,13 +5,13 @@ module Gizzard
5
5
 
6
6
  attr_reader :buffer
7
7
 
8
- def self.run(command_name, global_options, argv, subcommand_options, log)
8
+ def self.run(command_name, global_options, argv, subcommand_options, log, service=nil)
9
9
  command_class = Gizzard.const_get("#{classify(command_name)}Command")
10
- service = command_class.make_service(global_options, log)
10
+ service = command_class.make_service(global_options, log) if service.nil?
11
11
  command = command_class.new(service, global_options, argv, subcommand_options)
12
12
  command.run
13
13
  if command.buffer && command_name = global_options.render.shift
14
- run(command_name, service, global_options, command.buffer, OpenStruct.new)
14
+ run(command_name, global_options, command.buffer, OpenStruct.new, log, service)
15
15
  end
16
16
  end
17
17
 
@@ -86,7 +86,7 @@ module Gizzard
86
86
  end.reject do |forwarding|
87
87
  @command_options.table_ids && !@command_options.table_ids.include?(forwarding.table_id)
88
88
  end.each do |forwarding|
89
- output [ forwarding.table_id, forwarding.base_id, forwarding.shard_id.to_unix ].join("\t")
89
+ output [ forwarding.table_id, @command_options.hex ? ("%016x" % forwarding.base_id) : forwarding.base_id, forwarding.shard_id.to_unix ].join("\t")
90
90
  end
91
91
  end
92
92
  end
@@ -229,7 +229,7 @@ module Gizzard
229
229
  end
230
230
  end
231
231
  end
232
-
232
+
233
233
  class RepairCommand < ShardCommand
234
234
  def run
235
235
  args = @argv.dup.map{|a| a.split(/\s+/)}.flatten
@@ -289,7 +289,9 @@ module Gizzard
289
289
  end
290
290
 
291
291
  def run
292
- puts command_options.inspect
292
+ help! "No shards specified" if @argv.empty?
293
+ shards = []
294
+ command_options.write_only_shard ||= "com.twitter.gizzard.shards.WriteOnlyShard"
293
295
  additional_hosts = (command_options.hosts || "").split(/[\s,]+/)
294
296
  ids = @argv.map{|arg| ShardId.new(*arg.split("/")) rescue nil }.compact
295
297
  by_host = ids.inject({}) do |memo, id|
@@ -297,7 +299,7 @@ module Gizzard
297
299
  memo[id.hostname] << id
298
300
  memo
299
301
  end
300
-
302
+
301
303
  additional_hosts.each do |host|
302
304
  by_host[host] ||= NamedArray.new(host)
303
305
  end
@@ -312,7 +314,6 @@ module Gizzard
312
314
  end while longest.length > shortest.length + 1
313
315
 
314
316
  shard_info = nil
315
- puts sets.map{|l|l.length}.inspect
316
317
  sets.each do |set|
317
318
  host = set.name
318
319
  set.each do |id|
@@ -320,11 +321,17 @@ module Gizzard
320
321
  shard_info ||= service.get_shard(id)
321
322
  old = id.to_unix
322
323
  id.hostname = host
323
- puts "gizzmo create #{shard_info.class_name} -s '#{shard_info.source_type}' -d '#{shard_info.destination_type}' #{id.to_unix}"
324
- puts "gizzmo copy #{old} #{id.to_unix}"
324
+ shards << [old, id.to_unix]
325
325
  end
326
326
  end
327
327
  end
328
+
329
+ new_shards = shards.map{|(old, new)| new }
330
+
331
+ puts "gizzmo create #{shard_info.class_name} -s '#{shard_info.source_type}' -d '#{shard_info.destination_type}' #{new_shards.join(" ")}"
332
+ puts "gizzmo wrap #{command_options.write_only_shard} #{new_shards.join(" ")}"
333
+ shards.map {|(old, new)| puts "gizzmo copy #{old} #{new}" }
334
+ shards.map {|(old, new)| puts "gizzmo copy #{old} #{new}" }
328
335
  end
329
336
  end
330
337
 
@@ -359,8 +366,9 @@ module Gizzard
359
366
  displayed = {}
360
367
  overlaps.sort_by{|hosts, count| count }.reverse.each do |(host_a, host_b), count|
361
368
  next if !host_a || !host_b || displayed[host_a] || displayed[host_b]
362
- id_a = ids_by_host[host_a].first
363
- id_b = ids_by_host[host_b].first
369
+ id_a = ids_by_host[host_a].find{|id| service.list_upward_links(id).size > 0 }
370
+ id_b = ids_by_host[host_b].find{|id| service.list_upward_links(id).size > 0 }
371
+ next unless id_a && id_b
364
372
  weight_a = service.list_upward_links(id_a).first.weight
365
373
  weight_b = service.list_upward_links(id_b).first.weight
366
374
  if weight_a > weight_b
@@ -417,9 +425,15 @@ module Gizzard
417
425
 
418
426
  class LookupCommand < ShardCommand
419
427
  def run
420
- table_id, source_id = @argv
421
- help!("Requires table id and source id") unless table_id && source_id
422
- shard = service.find_current_forwarding(table_id.to_i, source_id.to_i)
428
+ table_id, source = @argv
429
+ help!("Requires table id and source") unless table_id && source
430
+ case @command_options.hash_function
431
+ when :fnv
432
+ source_id = Digest.fnv1a_64(source)
433
+ else
434
+ source_id = source.to_i
435
+ end
436
+ shard = service.find_current_forwarding(table_id.to_i, source_id)
423
437
  output shard.id.to_unix
424
438
  end
425
439
  end
@@ -521,4 +535,16 @@ module Gizzard
521
535
  STDERR.print "\n"
522
536
  end
523
537
  end
538
+
539
+ class FlushCommand < JobCommand
540
+ def run
541
+ args = @argv[0]
542
+ help!("Requires --all, or a job priority id.") unless args || command_options.flush_all
543
+ if command_options.flush_all
544
+ service.retry_errors()
545
+ else
546
+ service.retry_errors_for(args.to_i)
547
+ end
548
+ end
549
+ end
524
550
  end
@@ -0,0 +1,13 @@
1
+ module Gizzard
2
+ module Digest
3
+ def self.fnv1a_64(data)
4
+ prime = 1099511628211
5
+ rv = 0xcbf29ce484222325
6
+ data.each_byte do |byte|
7
+ rv = ((rv ^ (byte & 0xff)) * prime) & 0xffffffffffffffff
8
+ end
9
+ # trim to 60 bits for gizzard.
10
+ rv & 0x0fffffffffffffff
11
+ end
12
+ end
13
+ end
data/lib/gizzmo.rb CHANGED
@@ -9,7 +9,9 @@ require "yaml"
9
9
  DOC_STRINGS = {
10
10
  "create" => "Create shard(s) of a given Java/Scala class. If you don't know the list of available classes, you can just try a bogus class, and the exception will include a list of valid classes.",
11
11
  "wrap" => "Wrapping creates a new (virtual, e.g. blocking, replicating, etc.) shard, and relinks SHARD_ID_TO_WRAP's parent links to run through the new shard.",
12
- "inject" => "Inject jobs (as literal json) into the server. Jobs can be linefeed-terminated from stdin, or passed as arguments. Priority is server-defined, but typically lower numbers (like 1) are lower priority."
12
+ "inject" => "Inject jobs (as literal json) into the server. Jobs can be linefeed-terminated from stdin, or passed as arguments. Priority is server-defined, but typically lower numbers (like 1) are lower priority.",
13
+ "lookup" => "Lookup the shard id that holds the record for a given table / source_id.",
14
+ "flush" => "Flush error queue for a given priority."
13
15
  }
14
16
 
15
17
  ORIGINAL_ARGV = ARGV.dup
@@ -84,6 +86,10 @@ subcommands = {
84
86
  opts.banner = "Usage: #{zero} rebalance"
85
87
  separators(opts, DOC_STRINGS["rebalance"])
86
88
 
89
+ opts.on("-w", "--write-only=CLASS") do |w|
90
+ subcommand_options.write_only_shard = w
91
+ end
92
+
87
93
  opts.on("-h", "--hosts=list") do |h|
88
94
  subcommand_options.hosts = h
89
95
  end
@@ -128,6 +134,9 @@ subcommands = {
128
134
  subcommand_options.table_ids ||= []
129
135
  subcommand_options.table_ids += table_ids.split(",").map { |s| s.to_i }
130
136
  end
137
+ opts.on("-x", "--hex", "Show base ids in hex") do
138
+ subcommand_options.hex = true
139
+ end
131
140
  end,
132
141
  'unwrap' => OptionParser.new do |opts|
133
142
  opts.banner = "Usage: #{zero} unwrap SHARD_ID_TO_REMOVE [MORE SHARD_IDS]"
@@ -158,7 +167,7 @@ subcommands = {
158
167
  separators(opts, DOC_STRINGS["reload"])
159
168
  end,
160
169
  'addlink' => OptionParser.new do |opts|
161
- opts.banner = "Usage: #{zero} link PARENT_SHARD_ID CHILD_SHARD_ID WEIGHT"
170
+ opts.banner = "Usage: #{zero} addlink PARENT_SHARD_ID WEIGHT"
162
171
  separators(opts, DOC_STRINGS["addlink"])
163
172
  end,
164
173
  'unlink' => OptionParser.new do |opts|
@@ -166,8 +175,12 @@ subcommands = {
166
175
  separators(opts, DOC_STRINGS["unlink"])
167
176
  end,
168
177
  'lookup' => OptionParser.new do |opts|
169
- opts.banner = "Usage: #{zero} lookup TABLE_ID SOURCE_ID"
178
+ opts.banner = "Usage: #{zero} lookup [options] TABLE_ID SOURCE"
170
179
  separators(opts, DOC_STRINGS["lookup"])
180
+
181
+ opts.on("--fnv", "Use FNV1A_64 hash on source") do
182
+ subcommand_options.hash_function = :fnv
183
+ end
171
184
  end,
172
185
  'copy' => OptionParser.new do |opts|
173
186
  opts.banner = "Usage: #{zero} copy SOURCE_SHARD_ID DESTINATION_SHARD_ID"
@@ -188,6 +201,14 @@ subcommands = {
188
201
  'inject' => OptionParser.new do |opts|
189
202
  opts.banner = "Usage: #{zero} inject PRIORITY JOBS..."
190
203
  separators(opts, DOC_STRINGS["inject"])
204
+ end,
205
+ 'flush' => OptionParser.new do |opts|
206
+ opts.banner = "Usage: #{zero} flush --all|PRIORITY"
207
+ separators(opts, DOC_STRINGS["flush"])
208
+
209
+ opts.on("--all", "Flush all error queues.") do
210
+ subcommand_options.flush_all = true
211
+ end
191
212
  end
192
213
  }
193
214
 
@@ -227,7 +248,7 @@ global = OptionParser.new do |opts|
227
248
  end
228
249
 
229
250
  opts.on("-P", "--port=PORT", "PORT of remote thrift service") do |port|
230
- global_options.port = port
251
+ global_options.port = port.to_i
231
252
  end
232
253
 
233
254
  opts.on("-r", "--retry=TIMES", "TIMES to retry the command") do |r|
@@ -338,4 +359,4 @@ rescue Errno::EPIPE
338
359
  # seeing the backtrace is annoying!
339
360
  rescue Interrupt
340
361
  exit 1
341
- end
362
+ end
data/test/test.sh CHANGED
@@ -6,7 +6,7 @@ function g {
6
6
  }
7
7
 
8
8
  function expect {
9
- diff -u - "expected/$1" && echo " success." || echo " failed." && exit 1
9
+ diff -u - "expected/$1" && echo " success." || (echo " failed." && exit 1)
10
10
  }
11
11
 
12
12
  function expect-string {
@@ -19,9 +19,9 @@ g find -hlocalhost | expect empty-file.txt
19
19
 
20
20
  for i in {0..9}
21
21
  do
22
- g create localhost "table_repl_$i" com.twitter.service.flock.edges.ReplicatingShard
23
- g create localhost "table_a_$i" com.twitter.service.flock.edges.SqlShard --source-type="INT UNSIGNED" --destination-type="INT UNSIGNED"
24
- g create localhost "table_b_$i" com.twitter.service.flock.edges.SqlShard --source-type="INT UNSIGNED" --destination-type="INT UNSIGNED"
22
+ g create com.twitter.service.flock.edges.ReplicatingShard localhost/table_repl_$i
23
+ g create com.twitter.service.flock.edges.SqlShard localhost/table_a_$i --source-type="INT UNSIGNED" --destination-type="INT UNSIGNED"
24
+ g create com.twitter.service.flock.edges.SqlShard localhost/table_b_$i --source-type="INT UNSIGNED" --destination-type="INT UNSIGNED"
25
25
  g addlink "localhost/table_repl_$i" "localhost/table_a_$i" 2
26
26
  g addlink "localhost/table_repl_$i" "localhost/table_b_$i" 1
27
27
  done
@@ -52,6 +52,7 @@ g links localhost/replicating_table_b_0 | expect links-for-replicating_table_b_0
52
52
  g --subtree --info find -Hlocalhost | expect subtree-info.txt
53
53
 
54
54
  g lookup 1 100 | expect-string "localhost/forward_1"
55
+ g lookup --fnv 1 "hello" | expect-string "localhost/forward_1"
55
56
 
56
57
  g unwrap localhost/replicating_table_b_0 | expect unwrapped-replicating_table_b_0.txt
57
58
  g links localhost/table_b_0 | expect unwrapped-table_b_0.txt
@@ -72,4 +73,7 @@ do
72
73
  g addlink "localhost/table_deep_repl_$last" "localhost/table_deep_repl_$i" 2
73
74
  done
74
75
 
75
- g subtree localhost/table_deep_repl_5 | expect deep.txt
76
+ g subtree localhost/table_deep_repl_5 | expect deep.txt
77
+
78
+ g flush --all
79
+ g flush 1
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 0
9
- version: 0.7.0
8
+ - 4
9
+ version: 0.7.4
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-08-25 00:00:00 -07:00
17
+ date: 2010-10-04 00:00:00 -07:00
18
18
  default_executable: gizzmo
19
19
  dependencies: []
20
20
 
@@ -38,6 +38,7 @@ files:
38
38
  - gizzmo.gemspec
39
39
  - lib/gizzard.rb
40
40
  - lib/gizzard/commands.rb
41
+ - lib/gizzard/digest.rb
41
42
  - lib/gizzard/thrift.rb
42
43
  - lib/gizzmo.rb
43
44
  - lib/vendor/thrift_client/simple.rb