gizzmo 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/gizzmo.gemspec +3 -4
- data/lib/gizzard/commands.rb +96 -24
- data/lib/gizzard/thrift.rb +3 -3
- data/lib/gizzmo.rb +54 -9
- data/lib/vendor/thrift_client/simple.rb +19 -7
- metadata +3 -4
- data/.document +0 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.10.
|
1
|
+
0.10.1
|
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.10.
|
8
|
+
s.version = "0.10.1"
|
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{
|
12
|
+
s.date = %q{2011-01-05}
|
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}
|
@@ -19,8 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
"README.rdoc"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
|
-
".
|
23
|
-
".gitignore",
|
22
|
+
".gitignore",
|
24
23
|
"LICENSE",
|
25
24
|
"README.rdoc",
|
26
25
|
"Rakefile",
|
data/lib/gizzard/commands.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "pp"
|
2
2
|
require "digest/md5"
|
3
|
+
|
3
4
|
module Gizzard
|
4
5
|
class Command
|
5
6
|
include Thrift
|
@@ -17,7 +18,7 @@ module Gizzard
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def self.classify(string)
|
20
|
-
string.split(/\W+/).map{|s| s.capitalize }.join("")
|
21
|
+
string.split(/\W+/).map { |s| s.capitalize }.join("")
|
21
22
|
end
|
22
23
|
|
23
24
|
attr_reader :service, :global_options, :argv, :command_options
|
@@ -41,13 +42,13 @@ module Gizzard
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
class RetryProxy
|
46
47
|
def initialize(retries, object)
|
47
48
|
@inner = object
|
48
49
|
@retries_left = retries
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
def method_missing(*args)
|
52
53
|
@inner.send(*args)
|
53
54
|
rescue
|
@@ -63,15 +64,15 @@ module Gizzard
|
|
63
64
|
|
64
65
|
class ShardCommand < Command
|
65
66
|
def self.make_service(global_options, log)
|
66
|
-
RetryProxy.new global_options.retry.to_i,
|
67
|
-
Gizzard::Thrift::ShardManager.new(global_options.host, global_options.port, log, global_options.dry)
|
67
|
+
RetryProxy.new global_options.retry.to_i,
|
68
|
+
Gizzard::Thrift::ShardManager.new(global_options.host, global_options.port, log, global_options.framed, global_options.dry)
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
71
72
|
class JobCommand < Command
|
72
73
|
def self.make_service(global_options, log)
|
73
74
|
RetryProxy.new global_options.retry.to_i ,
|
74
|
-
Gizzard::Thrift::JobManager.new(global_options.host, global_options.port + 2, log, global_options.dry)
|
75
|
+
Gizzard::Thrift::JobManager.new(global_options.host, global_options.port + 2, log, global_options.framed, global_options.dry)
|
75
76
|
end
|
76
77
|
end
|
77
78
|
|
@@ -147,7 +148,18 @@ module Gizzard
|
|
147
148
|
class ReloadCommand < ShardCommand
|
148
149
|
def run
|
149
150
|
if global_options.force || ask
|
150
|
-
|
151
|
+
if @argv
|
152
|
+
# allow hosts to be given on the command line
|
153
|
+
@argv.each do |hostname|
|
154
|
+
output hostname
|
155
|
+
opts = global_options.dup
|
156
|
+
opts.host = hostname
|
157
|
+
s = self.class.make_service(opts, global_options.log || "./gizzmo.log")
|
158
|
+
s.reload_forwardings
|
159
|
+
end
|
160
|
+
else
|
161
|
+
service.reload_forwardings
|
162
|
+
end
|
151
163
|
else
|
152
164
|
STDERR.puts "aborted"
|
153
165
|
end
|
@@ -201,7 +213,10 @@ module Gizzard
|
|
201
213
|
upward_links = service.list_upward_links(shard_id)
|
202
214
|
downward_links = service.list_downward_links(shard_id)
|
203
215
|
|
204
|
-
|
216
|
+
if upward_links.length == 0 or downward_links.length == 0
|
217
|
+
STDERR.puts "Shard #{shard_id_string} must not be a root or leaf"
|
218
|
+
next
|
219
|
+
end
|
205
220
|
|
206
221
|
upward_links.each do |uplink|
|
207
222
|
downward_links.each do |downlink|
|
@@ -239,11 +254,15 @@ module Gizzard
|
|
239
254
|
shard_ids.each do |shard_id_text|
|
240
255
|
shard_id = ShardId.parse(shard_id_text)
|
241
256
|
next if !shard_id
|
242
|
-
|
243
|
-
|
257
|
+
unless command_options.down
|
258
|
+
service.list_upward_links(shard_id).each do |link_info|
|
259
|
+
output command_options.ids ? link_info.up_id.to_unix : link_info.to_unix
|
260
|
+
end
|
244
261
|
end
|
245
|
-
|
246
|
-
|
262
|
+
unless command_options.up
|
263
|
+
service.list_downward_links(shard_id).each do |link_info|
|
264
|
+
output command_options.ids ? link_info.down_id.to_unix : link_info.to_unix
|
265
|
+
end
|
247
266
|
end
|
248
267
|
end
|
249
268
|
end
|
@@ -406,7 +425,7 @@ module Gizzard
|
|
406
425
|
|
407
426
|
puts "gizzmo create #{shard_info.class_name} -s '#{shard_info.source_type}' -d '#{shard_info.destination_type}' #{new_shards.join(" ")}"
|
408
427
|
puts "gizzmo wrap #{command_options.write_only_shard} #{new_shards.join(" ")}"
|
409
|
-
shards.map {|(old, new)| puts "gizzmo copy #{old} #{new}" }
|
428
|
+
shards.map { |(old, new)| puts "gizzmo copy #{old} #{new}" }
|
410
429
|
end
|
411
430
|
end
|
412
431
|
|
@@ -433,16 +452,16 @@ module Gizzard
|
|
433
452
|
|
434
453
|
overlaps = {}
|
435
454
|
ids_by_table.values.each do |arr|
|
436
|
-
key = arr.map{|id| id.hostname }.sort
|
455
|
+
key = arr.map { |id| id.hostname }.sort
|
437
456
|
overlaps[key] ||= 0
|
438
|
-
overlaps[key]
|
457
|
+
overlaps[key] += 1
|
439
458
|
end
|
440
459
|
|
441
460
|
displayed = {}
|
442
|
-
overlaps.sort_by{|hosts, count| count }.reverse.each do |(host_a, host_b), count|
|
461
|
+
overlaps.sort_by { |hosts, count| count }.reverse.each do |(host_a, host_b), count|
|
443
462
|
next if !host_a || !host_b || displayed[host_a] || displayed[host_b]
|
444
|
-
id_a = ids_by_host[host_a].find{|id| service.list_upward_links(id).size > 0 }
|
445
|
-
id_b = ids_by_host[host_b].find{|id| service.list_upward_links(id).size > 0 }
|
463
|
+
id_a = ids_by_host[host_a].find { |id| service.list_upward_links(id).size > 0 }
|
464
|
+
id_b = ids_by_host[host_b].find { |id| service.list_upward_links(id).size > 0 }
|
446
465
|
next unless id_a && id_b
|
447
466
|
weight_a = service.list_upward_links(id_a).first.weight
|
448
467
|
weight_b = service.list_upward_links(id_b).first.weight
|
@@ -466,7 +485,6 @@ module Gizzard
|
|
466
485
|
|
467
486
|
class ReportCommand < ShardCommand
|
468
487
|
def run
|
469
|
-
|
470
488
|
things = @argv.map do |shard|
|
471
489
|
parse(down(ShardId.parse(shard))).join("\n")
|
472
490
|
end
|
@@ -492,20 +510,20 @@ module Gizzard
|
|
492
510
|
m[e] ||= []
|
493
511
|
m[e] << e
|
494
512
|
m
|
495
|
-
end.to_a.sort_by{|k, v| v.length}.reverse
|
513
|
+
end.to_a.sort_by { |k, v| v.length }.reverse
|
496
514
|
end
|
497
515
|
|
498
516
|
def parse(obj, id = nil, depth = 0, sub = true)
|
499
517
|
case obj
|
500
518
|
when Hash
|
501
519
|
id, prefix = parse(obj.keys.first, id, depth, sub)
|
502
|
-
[prefix] + parse(obj.values.first, id, depth + 1, sub)
|
520
|
+
[ prefix ] + parse(obj.values.first, id, depth + 1, sub)
|
503
521
|
when String
|
504
522
|
host, prefix = obj.split("/")
|
505
523
|
host = "db" if host != "localhost" && sub
|
506
|
-
id ||= prefix[/(\w+ward_)?\d+_\d+(_\w+ward)?/]
|
524
|
+
id ||= prefix[/(\w+ward_)?n?\d+_\d+(_\w+ward)?/]
|
507
525
|
prefix = (" " * depth) + host + "/" + ((sub && id) ? prefix.sub(id, "[ID]") : prefix)
|
508
|
-
[id, prefix]
|
526
|
+
[ id, prefix ]
|
509
527
|
when Array
|
510
528
|
obj.map do |e|
|
511
529
|
parse e, id, depth, sub
|
@@ -517,7 +535,7 @@ module Gizzard
|
|
517
535
|
vals = service.list_downward_links(id).map do |link|
|
518
536
|
down(link.down_id)
|
519
537
|
end
|
520
|
-
{id.to_unix => vals}
|
538
|
+
{ id.to_unix => vals }
|
521
539
|
end
|
522
540
|
end
|
523
541
|
|
@@ -575,6 +593,60 @@ module Gizzard
|
|
575
593
|
end
|
576
594
|
end
|
577
595
|
|
596
|
+
class SetupReplicaCommand < ShardCommand
|
597
|
+
def run
|
598
|
+
from_shard_id_string, to_shard_id_string = @argv
|
599
|
+
help!("Requires source & destination shard id") unless from_shard_id_string && to_shard_id_string
|
600
|
+
from_shard_id = ShardId.parse(from_shard_id_string)
|
601
|
+
to_shard_id = ShardId.parse(to_shard_id_string)
|
602
|
+
|
603
|
+
if service.list_upward_links(to_shard_id).size > 0
|
604
|
+
STDERR.puts "Destination shard #{to_shard_id} has links to it."
|
605
|
+
exit 1
|
606
|
+
end
|
607
|
+
|
608
|
+
link = service.list_upward_links(from_shard_id)[0]
|
609
|
+
replica_shard_id = link.up_id
|
610
|
+
weight = link.weight
|
611
|
+
write_only_shard_id = ShardId.new("localhost", "#{to_shard_id.table_prefix}_copy_write_only")
|
612
|
+
service.create_shard(ShardInfo.new(write_only_shard_id, "WriteOnlyShard", "", "", 0))
|
613
|
+
service.add_link(replica_shard_id, write_only_shard_id, weight)
|
614
|
+
service.add_link(write_only_shard_id, to_shard_id, 1)
|
615
|
+
output to_shard_id.to_unix
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
class FinishReplicaCommand < ShardCommand
|
620
|
+
def run
|
621
|
+
from_shard_id_string, to_shard_id_string = @argv
|
622
|
+
help!("Requires source & destination shard id") unless from_shard_id_string && to_shard_id_string
|
623
|
+
from_shard_id = ShardId.parse(from_shard_id_string)
|
624
|
+
to_shard_id = ShardId.parse(to_shard_id_string)
|
625
|
+
|
626
|
+
write_only_shard_id = ShardId.new("localhost", "#{to_shard_id.table_prefix}_copy_write_only")
|
627
|
+
link = service.list_upward_links(write_only_shard_id)[0]
|
628
|
+
replica_shard_id = link.up_id
|
629
|
+
weight = link.weight
|
630
|
+
|
631
|
+
# careful. need to validate some basic assumptions.
|
632
|
+
unless global_options.force
|
633
|
+
if service.list_upward_links(from_shard_id).map { |link| link.up_id }.to_a != [ replica_shard_id ]
|
634
|
+
STDERR.puts "Uplink from #{from_shard_id} is not a migration replica."
|
635
|
+
exit 1
|
636
|
+
end
|
637
|
+
if service.list_upward_links(to_shard_id).map { |link| link.up_id }.to_a != [ write_only_shard_id ]
|
638
|
+
STDERR.puts "Uplink from #{to_shard_id} is not a write-only barrier."
|
639
|
+
exit 1
|
640
|
+
end
|
641
|
+
end
|
642
|
+
|
643
|
+
service.remove_link(write_only_shard_id, to_shard_id)
|
644
|
+
service.remove_link(replica_shard_id, write_only_shard_id)
|
645
|
+
service.add_link(replica_shard_id, to_shard_id, weight)
|
646
|
+
service.delete_shard(write_only_shard_id)
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
578
650
|
class SetupMigrateCommand < ShardCommand
|
579
651
|
def run
|
580
652
|
from_shard_id_string, to_shard_id_string = @argv
|
data/lib/gizzard/thrift.rb
CHANGED
@@ -52,7 +52,7 @@ module Gizzard
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def to_unix
|
55
|
-
[id.to_unix, class_name, busy? ? "busy" : "
|
55
|
+
[id.to_unix, class_name, busy? ? "busy" : "ok"].join("\t")
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -91,8 +91,8 @@ module Gizzard
|
|
91
91
|
end
|
92
92
|
|
93
93
|
class GizzmoService < T::ThriftService
|
94
|
-
def initialize(host, port, log_path, dry_run = false)
|
95
|
-
super(host, port)
|
94
|
+
def initialize(host, port, log_path, framed, dry_run = false)
|
95
|
+
super(host, port, framed)
|
96
96
|
@dry = dry_run
|
97
97
|
begin
|
98
98
|
@log = File.open(log_path, "a")
|
data/lib/gizzmo.rb
CHANGED
@@ -7,11 +7,25 @@ require "gizzard"
|
|
7
7
|
require "yaml"
|
8
8
|
|
9
9
|
DOC_STRINGS = {
|
10
|
-
"
|
11
|
-
"
|
10
|
+
"addforwarding" => "Add a forwarding from a graph_id / base_source_id to a given shard.",
|
11
|
+
"addlink" => "Add a relationship link between two shards.",
|
12
|
+
"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.",
|
13
|
+
"drill" => "Show shard trees for replicas of a given structure signature (from 'report').",
|
14
|
+
"find" => "Show all shards with a given hostname.",
|
15
|
+
"finish-replica" => "Remove the write-only barrier in front of a shard that's finished being copied after 'setup-replica'.",
|
16
|
+
"flush" => "Flush error queue for a given priority.",
|
17
|
+
"forwardings" => "Get a list of all forwardings.",
|
18
|
+
"hosts" => "List hosts used in shard names in the forwarding table and replicas.",
|
19
|
+
"info" => "Show id/class/busy for shards.",
|
12
20
|
"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.",
|
21
|
+
"links" => "List parent & child links for shards.",
|
13
22
|
"lookup" => "Lookup the shard id that holds the record for a given table / source_id.",
|
14
|
-
"
|
23
|
+
"markbusy" => "Mark a shard as busy.",
|
24
|
+
"pair" => "Report the replica pairing structure for a list of hosts.",
|
25
|
+
"reload" => "Instruct an appserver to reload its nameserver state.",
|
26
|
+
"report" => "Show each unique replica structure for a given list of shards. Usually this shard list comes from << gizzmo forwardings | awk '{ print $3 }' >>.",
|
27
|
+
"setup-replica" => "Add a replica to be parallel to an existing replica, in write-only mode, ready to be copied to.",
|
28
|
+
"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.",
|
15
29
|
}
|
16
30
|
|
17
31
|
ORIGINAL_ARGV = ARGV.dup
|
@@ -20,6 +34,7 @@ zero = File.basename($0)
|
|
20
34
|
# Container for parsed options
|
21
35
|
global_options = OpenStruct.new
|
22
36
|
global_options.render = []
|
37
|
+
global_options.framed = false
|
23
38
|
subcommand_options = OpenStruct.new
|
24
39
|
|
25
40
|
# Leftover arguments
|
@@ -61,6 +76,12 @@ def separators(opts, string)
|
|
61
76
|
opts.separator("")
|
62
77
|
end
|
63
78
|
|
79
|
+
def load_config(options, filename)
|
80
|
+
YAML.load(File.open(filename)).each do |k, v|
|
81
|
+
options.send("#{k}=", v)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
64
85
|
subcommands = {
|
65
86
|
'create' => OptionParser.new do |opts|
|
66
87
|
opts.banner = "Usage: #{zero} create [options] CLASS_NAME SHARD_ID [MORE SHARD_IDS...]"
|
@@ -163,6 +184,16 @@ subcommands = {
|
|
163
184
|
'links' => OptionParser.new do |opts|
|
164
185
|
opts.banner = "Usage: #{zero} links SHARD_ID [MORE SHARD_IDS...]"
|
165
186
|
separators(opts, DOC_STRINGS["links"])
|
187
|
+
|
188
|
+
opts.on("--ids", "Show shard ids only") do
|
189
|
+
subcommand_options.ids = true
|
190
|
+
end
|
191
|
+
opts.on("--up", "Show uplinks only") do
|
192
|
+
subcommand_options.up = true
|
193
|
+
end
|
194
|
+
opts.on("--down", "show downlinks only") do
|
195
|
+
subcommand_options.down = true
|
196
|
+
end
|
166
197
|
end,
|
167
198
|
'info' => OptionParser.new do |opts|
|
168
199
|
opts.banner = "Usage: #{zero} info SHARD_ID [MORE SHARD_IDS...]"
|
@@ -209,6 +240,14 @@ subcommands = {
|
|
209
240
|
opts.banner = "Usage: #{zero} busy"
|
210
241
|
separators(opts, DOC_STRINGS["busy"])
|
211
242
|
end,
|
243
|
+
'setup-replica' => OptionParser.new do |opts|
|
244
|
+
opts.banner = "Usage: #{zero} setup-replica SOURCE_SHARD_ID DESTINATION_SHARD_ID"
|
245
|
+
separators(opts, DOC_STRINGS["setup-replica"])
|
246
|
+
end,
|
247
|
+
'finish-replica' => OptionParser.new do |opts|
|
248
|
+
opts.banner = "Usage: #{zero} finish-replica SOURCE_SHARD_ID DESTINATION_SHARD_ID"
|
249
|
+
separators(opts, DOC_STRINGS["finish-replica"])
|
250
|
+
end,
|
212
251
|
'setup-migrate' => OptionParser.new do |opts|
|
213
252
|
opts.banner = "Usage: #{zero} setup-migrate SOURCE_SHARD_ID DESTINATION_SHARD_ID"
|
214
253
|
separators(opts, DOC_STRINGS["setup-migrate"])
|
@@ -231,6 +270,10 @@ subcommands = {
|
|
231
270
|
end
|
232
271
|
}
|
233
272
|
|
273
|
+
if ENV['GIZZMORC']
|
274
|
+
load_config(global_options, ENV['GIZZMORC'])
|
275
|
+
end
|
276
|
+
|
234
277
|
global = OptionParser.new do |opts|
|
235
278
|
opts.banner = "Usage: #{zero} [global-options] SUBCOMMAND [subcommand-options]"
|
236
279
|
opts.separator ""
|
@@ -243,7 +286,7 @@ global = OptionParser.new do |opts|
|
|
243
286
|
opts.separator ""
|
244
287
|
opts.separator "You may find it useful to create a ~/.gizzmorc file, which is simply YAML"
|
245
288
|
opts.separator "key/value pairs corresponding to options you want by default. A common .gizzmorc"
|
246
|
-
opts.separator "simply
|
289
|
+
opts.separator "simply contains:"
|
247
290
|
opts.separator ""
|
248
291
|
opts.separator " host: localhost"
|
249
292
|
opts.separator " port: 7917"
|
@@ -270,6 +313,10 @@ global = OptionParser.new do |opts|
|
|
270
313
|
global_options.port = port.to_i
|
271
314
|
end
|
272
315
|
|
316
|
+
opts.on("-F", "--framed", "use the thrift framed transport") do |framed|
|
317
|
+
global_options.framed = true
|
318
|
+
end
|
319
|
+
|
273
320
|
opts.on("-r", "--retry=TIMES", "TIMES to retry the command") do |r|
|
274
321
|
global_options.retry = r
|
275
322
|
end
|
@@ -290,10 +337,8 @@ global = OptionParser.new do |opts|
|
|
290
337
|
global_options.dry = true
|
291
338
|
end
|
292
339
|
|
293
|
-
opts.on("-C", "--config=YAML_FILE", "YAML_FILE of option key/values") do |
|
294
|
-
|
295
|
-
global_options.send("#{k}=", v)
|
296
|
-
end
|
340
|
+
opts.on("-C", "--config=YAML_FILE", "YAML_FILE of option key/values") do |filename|
|
341
|
+
load_config(global_options, filename)
|
297
342
|
end
|
298
343
|
|
299
344
|
opts.on("-L", "--log=LOG_FILE", "Path to LOG_FILE") do |file|
|
@@ -370,7 +415,7 @@ def custom_timeout(seconds)
|
|
370
415
|
end
|
371
416
|
end
|
372
417
|
|
373
|
-
begin
|
418
|
+
begin
|
374
419
|
custom_timeout(global_options.timeout) do
|
375
420
|
Gizzard::Command.run(subcommand_name, global_options, argv, subcommand_options, log)
|
376
421
|
end
|
@@ -87,8 +87,14 @@ class ThriftClient
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
def pack_request(method_name, arg_struct, request_id=0)
|
91
|
-
[ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*")
|
90
|
+
def pack_request(method_name, arg_struct, framed, request_id=0)
|
91
|
+
msg = [ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*")
|
92
|
+
if framed
|
93
|
+
frame = [ msg.length ].pack("N")
|
94
|
+
frame + msg
|
95
|
+
else
|
96
|
+
msg
|
97
|
+
end
|
92
98
|
end
|
93
99
|
|
94
100
|
def read_value(s, type)
|
@@ -169,8 +175,13 @@ class ThriftClient
|
|
169
175
|
end
|
170
176
|
end
|
171
177
|
end
|
172
|
-
|
173
|
-
def read_response(s, rv_class)
|
178
|
+
|
179
|
+
def read_response(s, rv_class, framed)
|
180
|
+
if framed
|
181
|
+
# unwrap frame size. dont use for now
|
182
|
+
framesize = s.read(4).unpack("N")
|
183
|
+
end
|
184
|
+
|
174
185
|
version, message_type, method_name_len = s.read(8).unpack("nnN")
|
175
186
|
method_name = s.read(method_name_len)
|
176
187
|
seq_id = s.read(4).unpack("N").first
|
@@ -280,9 +291,10 @@ class ThriftClient
|
|
280
291
|
UnknownStruct = make_struct(:Unknown)
|
281
292
|
|
282
293
|
class ThriftService
|
283
|
-
def initialize(host, port)
|
294
|
+
def initialize(host, port, framed = false)
|
284
295
|
@host = host
|
285
296
|
@port = port
|
297
|
+
@framed = framed
|
286
298
|
end
|
287
299
|
|
288
300
|
def self._arg_structs
|
@@ -310,8 +322,8 @@ class ThriftClient
|
|
310
322
|
arg_class, rv_class = cls._arg_structs[method_name.to_sym]
|
311
323
|
arg_struct = arg_class.new(*args)
|
312
324
|
sock = TCPSocket.new(@host, @port)
|
313
|
-
sock.write(ThriftClient::Simple.pack_request(method_name, arg_struct))
|
314
|
-
rv = ThriftClient::Simple.read_response(sock, rv_class)
|
325
|
+
sock.write(ThriftClient::Simple.pack_request(method_name, arg_struct, @framed))
|
326
|
+
rv = ThriftClient::Simple.read_response(sock, rv_class, @framed)
|
315
327
|
sock.close
|
316
328
|
rv[2]
|
317
329
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 10
|
8
|
-
-
|
9
|
-
version: 0.10.
|
8
|
+
- 1
|
9
|
+
version: 0.10.1
|
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:
|
17
|
+
date: 2011-01-05 00:00:00 -08:00
|
18
18
|
default_executable: gizzmo
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -28,7 +28,6 @@ extra_rdoc_files:
|
|
28
28
|
- LICENSE
|
29
29
|
- README.rdoc
|
30
30
|
files:
|
31
|
-
- .document
|
32
31
|
- .gitignore
|
33
32
|
- LICENSE
|
34
33
|
- README.rdoc
|