gizzmo 0.2.1 → 0.3.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/.gitignore CHANGED
@@ -19,3 +19,4 @@ rdoc
19
19
  pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
+ tmp
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.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.2.1"
8
+ s.version = "0.3.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-06-30}
12
+ s.date = %q{2010-07-09}
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}
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
43
43
  "test/expected/links-for-table_b_0.txt",
44
44
  "test/expected/links-for-table_repl_0.txt",
45
45
  "test/expected/original-find.txt",
46
+ "test/expected/subtree-info.txt",
46
47
  "test/expected/subtree.txt",
47
48
  "test/expected/unwrapped-replicating_table_b_0.txt",
48
49
  "test/expected/unwrapped-table_b_0.txt",
@@ -2,9 +2,15 @@ require "pp"
2
2
  module Gizzard
3
3
  class Command
4
4
  include Thrift
5
+
6
+ attr_reader :buffer
5
7
 
6
- def self.run(command_name, *args)
7
- Gizzard.const_get("#{classify(command_name)}Command").new(*args).run
8
+ def self.run(command_name, service, global_options, argv, subcommand_options)
9
+ command = Gizzard.const_get("#{classify(command_name)}Command").new(service, global_options, argv, subcommand_options)
10
+ command.run
11
+ if command.buffer && command_name = global_options.render.shift
12
+ run(command_name, service, global_options, command.buffer, OpenStruct.new)
13
+ end
8
14
  end
9
15
 
10
16
  def self.classify(string)
@@ -22,8 +28,17 @@ module Gizzard
22
28
  def help!(message = nil)
23
29
  raise HelpNeededError, message
24
30
  end
31
+
32
+ def output(string)
33
+ if global_options.render.any?
34
+ @buffer ||= []
35
+ @buffer << string.strip
36
+ else
37
+ puts string
38
+ end
39
+ end
25
40
  end
26
-
41
+
27
42
  class AddforwardingCommand < Command
28
43
  def run
29
44
  help! if argv.length != 3
@@ -40,7 +55,7 @@ module Gizzard
40
55
  end.reject do |forwarding|
41
56
  @command_options.table_ids && !@command_options.table_ids.include?(forwarding.table_id)
42
57
  end.each do |forwarding|
43
- puts [ forwarding.table_id, forwarding.base_id, forwarding.shard_id.to_unix ].join("\t")
58
+ output [ forwarding.table_id, forwarding.base_id, forwarding.shard_id.to_unix ].join("\t")
44
59
  end
45
60
  end
46
61
  end
@@ -53,24 +68,24 @@ module Gizzard
53
68
  @roots << up(@id)
54
69
  end
55
70
  @roots.uniq.each do |root|
56
- puts root.to_unix
57
- down(root, 1)
71
+ output root.to_unix
72
+ down(root, 1)
58
73
  end
59
74
  end
60
-
75
+
61
76
  def up(id)
62
77
  links = service.list_upward_links(id)
63
78
  if links.empty?
64
79
  id
65
80
  else
66
- links.map{|link| link.up_id }.find{|up_id| up(up_id) }
81
+ links.map { |link| link.up_id }.find { |up_id| up(up_id) }
67
82
  end
68
83
  end
69
84
 
70
85
  def down(id, depth = 0)
71
86
  service.list_downward_links(id).map do |link|
72
87
  printable = " " * depth + link.down_id.to_unix
73
- puts printable
88
+ output printable
74
89
  down(link.down_id, depth + 1)
75
90
  end
76
91
  end
@@ -84,10 +99,10 @@ module Gizzard
84
99
  STDERR.puts "aborted"
85
100
  end
86
101
  end
87
-
102
+
88
103
  def ask
89
- puts "Are you sure? Reloading will affect production services immediately! (Type 'yes')"
90
- gets.chomp == "yes"
104
+ output "Are you sure? Reloading will affect production services immediately! (Type 'yes')"
105
+ gets.chomp == "yes"
91
106
  end
92
107
  end
93
108
 
@@ -96,7 +111,7 @@ module Gizzard
96
111
  argv.each do |arg|
97
112
  id = ShardId.parse(arg)
98
113
  service.delete_shard(id)
99
- puts id.to_unix
114
+ output id.to_unix
100
115
  end
101
116
  end
102
117
  end
@@ -106,19 +121,19 @@ module Gizzard
106
121
  up_id, down_id, weight = argv
107
122
  help! if argv.length != 3
108
123
  weight = weight.to_i
109
- up_id = ShardId.parse(up_id)
110
- down_id = ShardId.parse(down_id)
124
+ up_id = ShardId.parse(up_id)
125
+ down_id = ShardId.parse(down_id)
111
126
  link = LinkInfo.new(up_id, down_id, weight)
112
127
  service.add_link(link.up_id, link.down_id, link.weight)
113
- puts link.to_unix
128
+ output link.to_unix
114
129
  end
115
130
  end
116
131
 
117
132
  class UnlinkCommand < Command
118
133
  def run
119
134
  up_id, down_id = argv
120
- up_id = ShardId.parse(up_id)
121
- down_id = ShardId.parse(down_id)
135
+ up_id = ShardId.parse(up_id)
136
+ down_id = ShardId.parse(down_id)
122
137
  service.remove_link(up_id, down_id)
123
138
  end
124
139
  end
@@ -128,14 +143,14 @@ module Gizzard
128
143
  shard_ids = argv
129
144
  help! "No shards specified" if shard_ids.empty?
130
145
  shard_ids.each do |shard_id_string|
131
- shard_id = ShardId.parse(shard_id_string)
146
+ shard_id = ShardId.parse(shard_id_string)
132
147
  service.list_upward_links(shard_id).each do |uplink|
133
148
  service.list_downward_links(shard_id).each do |downlink|
134
149
  service.add_link(uplink.up_id, downlink.down_id, uplink.weight)
135
150
  new_link = LinkInfo.new(uplink.up_id, downlink.down_id, uplink.weight)
136
151
  service.remove_link(uplink.up_id, uplink.down_id)
137
152
  service.remove_link(downlink.up_id, downlink.down_id)
138
- puts new_link.to_unix
153
+ output new_link.to_unix
139
154
  end
140
155
  end
141
156
  service.delete_shard shard_id
@@ -152,7 +167,7 @@ module Gizzard
152
167
  destination_type = command_options.destination_type || ""
153
168
  service.create_shard(ShardInfo.new(shard_id = ShardId.new(host, table), class_name, source_type, destination_type, busy))
154
169
  service.get_shard(shard_id)
155
- puts shard_id.to_unix
170
+ output shard_id.to_unix
156
171
  end
157
172
  end
158
173
 
@@ -162,10 +177,10 @@ module Gizzard
162
177
  shard_ids.each do |shard_id_text|
163
178
  shard_id = ShardId.parse(shard_id_text)
164
179
  service.list_upward_links(shard_id).each do |link_info|
165
- puts link_info.to_unix
180
+ output link_info.to_unix
166
181
  end
167
182
  service.list_downward_links(shard_id).each do |link_info|
168
- puts link_info.to_unix
183
+ output link_info.to_unix
169
184
  end
170
185
  end
171
186
  end
@@ -176,7 +191,7 @@ module Gizzard
176
191
  shard_ids = @argv
177
192
  shard_ids.each do |shard_id|
178
193
  shard_info = service.get_shard(ShardId.parse(shard_id))
179
- puts shard_info.to_unix
194
+ output shard_info.to_unix
180
195
  end
181
196
  end
182
197
  end
@@ -203,7 +218,7 @@ module Gizzard
203
218
  service.remove_link(link_info.up_id, link_info.down_id)
204
219
  end
205
220
  end
206
- puts wrapper_id.to_unix
221
+ output wrapper_id.to_unix
207
222
  end
208
223
  end
209
224
  end
@@ -213,8 +228,17 @@ module Gizzard
213
228
  help!("host is a required option") unless command_options.shard_host
214
229
  service.shards_for_hostname(command_options.shard_host).each do |shard|
215
230
  next if command_options.shard_type && shard.class_name !~ Regexp.new(command_options.shard_type)
216
- puts shard.id.to_unix
231
+ output shard.id.to_unix
217
232
  end
218
233
  end
219
234
  end
220
- end
235
+
236
+ class LookupCommand < Command
237
+ def run
238
+ table_id, source_id = @argv
239
+ help!("Requires table id and source id") unless table_id && source_id
240
+ shard = service.find_current_forwarding(table_id.to_i, source_id.to_i)
241
+ output shard.id.to_unix
242
+ end
243
+ end
244
+ end
@@ -22,9 +22,9 @@ module Gizzard
22
22
  def inspect
23
23
  "#{hostname}/#{table_prefix}"
24
24
  end
25
-
25
+
26
26
  alias_method :to_unix, :inspect
27
-
27
+
28
28
  def self.parse(string)
29
29
  new(*string.split("/"))
30
30
  end
@@ -46,7 +46,7 @@ module Gizzard
46
46
  def inspect(short = false)
47
47
  "#{id.inspect}" + (busy? ? " (BUSY)" : "")
48
48
  end
49
-
49
+
50
50
  def to_unix
51
51
  [id.to_unix, class_name, busy? ? "busy" : "unbusy"].join("\t")
52
52
  end
@@ -62,11 +62,10 @@ module Gizzard
62
62
  def inspect
63
63
  "#{up_id.inspect} -> #{down_id.inspect}" + (weight == 1 ? "" : " <#{weight}>")
64
64
  end
65
-
65
+
66
66
  def to_unix
67
67
  [up_id.to_unix, down_id.to_unix, weight].join("\t")
68
68
  end
69
-
70
69
  end
71
70
 
72
71
  ShardMigration = T.make_struct(:ShardMigration,
@@ -97,11 +96,11 @@ module Gizzard
97
96
  STDERR.puts "Error opening log file at #{log_path}. Continuing..."
98
97
  end
99
98
  end
100
-
99
+
101
100
  def _proxy(method_name, *args)
102
101
  cls = self.class.ancestors.find { |cls| cls.respond_to?(:_arg_structs) and cls._arg_structs[method_name.to_sym] }
103
102
  arg_class, rv_class = cls._arg_structs[method_name.to_sym]
104
-
103
+
105
104
  # Writing methods return void. Methods should never both read and write. If this assumption
106
105
  # is violated in the future, dry-run will fail!!
107
106
  is_writing_method = rv_class._fields.first.type == ThriftClient::Simple::VOID
@@ -118,13 +117,13 @@ module Gizzard
118
117
  raise
119
118
  end
120
119
  end
121
-
120
+
122
121
  def printable(method_name, args, timestamp = false)
123
122
  ts = timestamp ? "#{Time.now}\t" : ""
124
123
  "#{ts}#{method_name}(#{args.map{|a| a.inspect}.join(', ')})"
125
124
  end
126
-
127
-
125
+
126
+
128
127
  thrift_method :create_shard, void, field(:shard, struct(ShardInfo), 1), :throws => exception(ShardException)
129
128
  thrift_method :delete_shard, void, field(:id, struct(ShardId), 1)
130
129
  thrift_method :get_shard, struct(ShardInfo), field(:id, struct(ShardId), 1)
data/lib/gizzmo.rb CHANGED
@@ -10,6 +10,7 @@ ORIGINAL_ARGV = ARGV.dup
10
10
 
11
11
  # Container for parsed options
12
12
  global_options = OpenStruct.new
13
+ global_options.render = []
13
14
  subcommand_options = OpenStruct.new
14
15
 
15
16
  # Leftover arguments
@@ -51,7 +52,7 @@ subcommands = {
51
52
  end,
52
53
  'forwardings' => OptionParser.new do |opts|
53
54
  opts.banner = "Usage: #{$0} show [options]"
54
-
55
+
55
56
  opts.on("-t", "--tables=IDS", "Show only the specified table ids (comma separated)") do |table_ids|
56
57
  subcommand_options.table_ids ||= []
57
58
  subcommand_options.table_ids += table_ids.split(",").map { |s| s.to_i }
@@ -85,6 +86,9 @@ subcommands = {
85
86
  end,
86
87
  'unlink' => OptionParser.new do |opts|
87
88
  opts.banner = "Usage: #{$0} unlink PARENT_SHARD_ID CHILD_SHARD_ID"
89
+ end,
90
+ 'lookup' => OptionParser.new do |opts|
91
+ opts.banner = "Usage: #{$0} lookup TABLE_ID SOURCE_ID"
88
92
  end
89
93
  }
90
94
 
@@ -107,6 +111,14 @@ global = OptionParser.new do |opts|
107
111
  opts.on("-P", "--port=PORT", "PORT of remote thrift service") do |port|
108
112
  global_options.port = port
109
113
  end
114
+
115
+ opts.on("--subtree", "Render in subtree mode") do
116
+ global_options.render << "subtree"
117
+ end
118
+
119
+ opts.on("--info", "Render in info mode") do
120
+ global_options.render << "info"
121
+ end
110
122
 
111
123
  opts.on("-D", "--dry-run", "") do |port|
112
124
  global_options.dry = true
@@ -121,7 +133,7 @@ global = OptionParser.new do |opts|
121
133
  opts.on("-L", "--log=LOG_FILE", "Path to LOG_FILE") do |file|
122
134
  global_options.log = file
123
135
  end
124
-
136
+
125
137
  opts.on("-f", "--force", "Don't display confirmation dialogs") do |force|
126
138
  global_options.force = force
127
139
  end
@@ -0,0 +1,33 @@
1
+ localhost/table_repl_0 com.twitter.service.flock.edges.ReplicatingShard unbusy
2
+ localhost/table_a_0 com.twitter.service.flock.edges.SqlShard unbusy
3
+ localhost/replicating_table_b_0 com.twitter.service.flock.edges.ReplicatingShard unbusy
4
+ localhost/table_b_0 com.twitter.service.flock.edges.SqlShard unbusy
5
+ localhost/table_repl_1 com.twitter.service.flock.edges.ReplicatingShard unbusy
6
+ localhost/table_a_1 com.twitter.service.flock.edges.SqlShard unbusy
7
+ localhost/table_b_1 com.twitter.service.flock.edges.SqlShard unbusy
8
+ localhost/table_repl_2 com.twitter.service.flock.edges.ReplicatingShard unbusy
9
+ localhost/table_a_2 com.twitter.service.flock.edges.SqlShard unbusy
10
+ localhost/table_b_2 com.twitter.service.flock.edges.SqlShard unbusy
11
+ localhost/table_repl_3 com.twitter.service.flock.edges.ReplicatingShard unbusy
12
+ localhost/table_a_3 com.twitter.service.flock.edges.SqlShard unbusy
13
+ localhost/table_b_3 com.twitter.service.flock.edges.SqlShard unbusy
14
+ localhost/table_repl_4 com.twitter.service.flock.edges.ReplicatingShard unbusy
15
+ localhost/table_a_4 com.twitter.service.flock.edges.SqlShard unbusy
16
+ localhost/table_b_4 com.twitter.service.flock.edges.SqlShard unbusy
17
+ localhost/table_repl_5 com.twitter.service.flock.edges.ReplicatingShard unbusy
18
+ localhost/table_a_5 com.twitter.service.flock.edges.SqlShard unbusy
19
+ localhost/table_b_5 com.twitter.service.flock.edges.SqlShard unbusy
20
+ localhost/table_repl_6 com.twitter.service.flock.edges.ReplicatingShard unbusy
21
+ localhost/table_a_6 com.twitter.service.flock.edges.SqlShard unbusy
22
+ localhost/table_b_6 com.twitter.service.flock.edges.SqlShard unbusy
23
+ localhost/table_repl_7 com.twitter.service.flock.edges.ReplicatingShard unbusy
24
+ localhost/table_a_7 com.twitter.service.flock.edges.SqlShard unbusy
25
+ localhost/table_b_7 com.twitter.service.flock.edges.SqlShard unbusy
26
+ localhost/table_repl_8 com.twitter.service.flock.edges.ReplicatingShard unbusy
27
+ localhost/table_a_8 com.twitter.service.flock.edges.SqlShard unbusy
28
+ localhost/table_b_8 com.twitter.service.flock.edges.SqlShard unbusy
29
+ localhost/table_repl_9 com.twitter.service.flock.edges.ReplicatingShard unbusy
30
+ localhost/table_a_9 com.twitter.service.flock.edges.SqlShard unbusy
31
+ localhost/table_b_9 com.twitter.service.flock.edges.SqlShard unbusy
32
+ localhost/replicating_table_b_0 com.twitter.service.flock.edges.ReplicatingShard unbusy
33
+ localhost/table_b_0 com.twitter.service.flock.edges.SqlShard unbusy
data/test/test.sh CHANGED
@@ -9,6 +9,11 @@ function expect {
9
9
  diff -u - "expected/$1" && echo " success." || echo " failed." && exit 1
10
10
  }
11
11
 
12
+ function expect-string {
13
+ echo "$1" > expected/tmp
14
+ expect tmp
15
+ }
16
+
12
17
  g find -hlocalhost | xargs ../bin/gizzmo -Cconfig.yaml delete
13
18
  g find -hlocalhost | expect empty-file.txt
14
19
 
@@ -25,9 +30,17 @@ for i in `g find -h localhost`; do g info $i; done | expect info.txt
25
30
  g find -hlocalhost | expect original-find.txt
26
31
  g find -hlocalhost -tSqlShard | expect find-only-sql-shard-type.txt
27
32
 
28
- g addforwarding 1 0 localhost/table_a_3
29
- g forwardings | expect forwardings.txt
30
- g unforward 1 0 localhost/table_a_3
33
+
34
+ NOW=`date +%s` # unix timestamp
35
+ g addforwarding 13 $NOW localhost/table_a_3
36
+
37
+ g forwardings | egrep "13.$NOW.localhost/table_a_3"
38
+ if [ $? -ne 0 ]; then
39
+ echo " failed."
40
+ exit 1
41
+ fi
42
+
43
+ # g unforward 1 0 localhost/table_a_3
31
44
 
32
45
  g -D wrap com.twitter.service.flock.edges.ReplicatingShard localhost/table_b_0 | expect dry-wrap-table_b_0.txt
33
46
  g wrap com.twitter.service.flock.edges.ReplicatingShard localhost/table_b_0 | expect wrap-table_b_0.txt
@@ -36,6 +49,10 @@ g links localhost/table_b_0 | expect links-for-table_b_0.txt
36
49
  g links localhost/table_repl_0 | expect links-for-table_repl_0.txt
37
50
  g links localhost/replicating_table_b_0 | expect links-for-replicating_table_b_0.txt
38
51
 
52
+ g --subtree --info find -Hlocalhost | expect subtree-info.txt
53
+
54
+ g lookup 1 100 | expect-string "localhost/forward_1"
55
+
39
56
  g unwrap localhost/replicating_table_b_0 | expect unwrapped-replicating_table_b_0.txt
40
57
  g links localhost/table_b_0 | expect unwrapped-table_b_0.txt
41
58
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.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-06-30 00:00:00 -07:00
17
+ date: 2010-07-09 00:00:00 -07:00
18
18
  default_executable: gizzmo
19
19
  dependencies: []
20
20
 
@@ -52,6 +52,7 @@ files:
52
52
  - test/expected/links-for-table_b_0.txt
53
53
  - test/expected/links-for-table_repl_0.txt
54
54
  - test/expected/original-find.txt
55
+ - test/expected/subtree-info.txt
55
56
  - test/expected/subtree.txt
56
57
  - test/expected/unwrapped-replicating_table_b_0.txt
57
58
  - test/expected/unwrapped-table_b_0.txt