thrift 0.0.751142
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/CHANGELOG +2 -0
- data/COPYING +14 -0
- data/LICENSE +14 -0
- data/Makefile.am +15 -0
- data/Manifest +78 -0
- data/README +30 -0
- data/Rakefile +102 -0
- data/benchmark/Benchmark.thrift +5 -0
- data/benchmark/benchmark.rb +254 -0
- data/benchmark/client.rb +56 -0
- data/benchmark/gen-rb/BenchmarkService.rb +81 -0
- data/benchmark/gen-rb/Benchmark_constants.rb +11 -0
- data/benchmark/gen-rb/Benchmark_types.rb +10 -0
- data/benchmark/server.rb +64 -0
- data/benchmark/thin_server.rb +26 -0
- data/ext/binary_protocol_accelerated.c +463 -0
- data/ext/binary_protocol_accelerated.h +1 -0
- data/ext/constants.h +77 -0
- data/ext/extconf.rb +7 -0
- data/ext/memory_buffer.c +52 -0
- data/ext/memory_buffer.h +1 -0
- data/ext/protocol.c +166 -0
- data/ext/protocol.h +1 -0
- data/ext/struct.c +574 -0
- data/ext/struct.h +48 -0
- data/ext/thrift_native.c +173 -0
- data/lib/thrift/client.rb +44 -0
- data/lib/thrift/deprecation.rb +155 -0
- data/lib/thrift/exceptions.rb +65 -0
- data/lib/thrift/processor.rb +39 -0
- data/lib/thrift/protocol/binaryprotocol.rb +213 -0
- data/lib/thrift/protocol/binaryprotocolaccelerated.rb +19 -0
- data/lib/thrift/protocol/tbinaryprotocol.rb +2 -0
- data/lib/thrift/protocol/tprotocol.rb +2 -0
- data/lib/thrift/protocol.rb +270 -0
- data/lib/thrift/serializer.rb +27 -0
- data/lib/thrift/server/httpserver.rb +44 -0
- data/lib/thrift/server/nonblockingserver.rb +278 -0
- data/lib/thrift/server/thttpserver.rb +2 -0
- data/lib/thrift/server/tserver.rb +2 -0
- data/lib/thrift/server.rb +135 -0
- data/lib/thrift/struct.rb +272 -0
- data/lib/thrift/thrift.rb +14 -0
- data/lib/thrift/transport/httpclient.rb +29 -0
- data/lib/thrift/transport/socket.rb +167 -0
- data/lib/thrift/transport/thttpclient.rb +2 -0
- data/lib/thrift/transport/tsocket.rb +2 -0
- data/lib/thrift/transport/ttransport.rb +2 -0
- data/lib/thrift/transport/unixsocket.rb +58 -0
- data/lib/thrift/transport.rb +319 -0
- data/lib/thrift/types.rb +83 -0
- data/lib/thrift.rb +28 -0
- data/setup.rb +1585 -0
- data/spec/ThriftSpec.thrift +46 -0
- data/spec/backwards_compatibility_spec.rb +136 -0
- data/spec/binaryprotocol_spec.rb +45 -0
- data/spec/binaryprotocol_spec_shared.rb +274 -0
- data/spec/binaryprotocolaccelerated_spec.rb +101 -0
- data/spec/client_spec.rb +81 -0
- data/spec/deprecation_spec.rb +443 -0
- data/spec/exception_spec.rb +123 -0
- data/spec/gen-rb/NonblockingService.rb +268 -0
- data/spec/gen-rb/ThriftSpec_constants.rb +11 -0
- data/spec/gen-rb/ThriftSpec_types.rb +134 -0
- data/spec/httpclient_spec.rb +31 -0
- data/spec/httpserver_spec.rb +98 -0
- data/spec/nonblockingserver_spec.rb +245 -0
- data/spec/processor_spec.rb +64 -0
- data/spec/protocol_spec.rb +142 -0
- data/spec/serializer_spec.rb +52 -0
- data/spec/server_spec.rb +141 -0
- data/spec/socket_spec.rb +97 -0
- data/spec/socket_spec_shared.rb +85 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/struct_spec.rb +244 -0
- data/spec/transport_spec.rb +359 -0
- data/spec/types_spec.rb +98 -0
- data/spec/unixsocket_spec.rb +90 -0
- data/thrift.gemspec +33 -0
- data.tar.gz.sig +0 -0
- metadata +200 -0
- metadata.gz.sig +0 -0
data/CHANGELOG
ADDED
data/COPYING
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Apache Software License
|
2
|
+
Copyright (c) 2006- Facebook, Inc. et al.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Apache Software License
|
2
|
+
Copyright (c) 2006- Facebook, Inc. et al.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
data/Makefile.am
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
EXTRA_DIST = setup.rb lib ext
|
2
|
+
|
3
|
+
all-local:
|
4
|
+
$(RUBY) setup.rb config
|
5
|
+
$(RUBY) setup.rb setup
|
6
|
+
|
7
|
+
install-exec-hook:
|
8
|
+
$(RUBY) setup.rb install
|
9
|
+
|
10
|
+
# Make sure this doesn't fail if Ruby is not configured.
|
11
|
+
clean-local:
|
12
|
+
RUBY=$(RUBY) ; if test -z "$$RUBY" ; then RUBY=: ; fi ; \
|
13
|
+
$$RUBY setup.rb clean
|
14
|
+
|
15
|
+
check-local: all
|
data/Manifest
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
COPYING
|
3
|
+
LICENSE
|
4
|
+
Makefile.am
|
5
|
+
Manifest
|
6
|
+
README
|
7
|
+
Rakefile
|
8
|
+
benchmark/Benchmark.thrift
|
9
|
+
benchmark/benchmark.rb
|
10
|
+
benchmark/client.rb
|
11
|
+
benchmark/gen-rb/BenchmarkService.rb
|
12
|
+
benchmark/gen-rb/Benchmark_constants.rb
|
13
|
+
benchmark/gen-rb/Benchmark_types.rb
|
14
|
+
benchmark/server.rb
|
15
|
+
benchmark/thin_server.rb
|
16
|
+
ext/binary_protocol_accelerated.c
|
17
|
+
ext/binary_protocol_accelerated.h
|
18
|
+
ext/constants.h
|
19
|
+
ext/extconf.rb
|
20
|
+
ext/memory_buffer.c
|
21
|
+
ext/memory_buffer.h
|
22
|
+
ext/protocol.c
|
23
|
+
ext/protocol.h
|
24
|
+
ext/struct.c
|
25
|
+
ext/struct.h
|
26
|
+
ext/thrift_native.c
|
27
|
+
lib/thrift.rb
|
28
|
+
lib/thrift/client.rb
|
29
|
+
lib/thrift/deprecation.rb
|
30
|
+
lib/thrift/exceptions.rb
|
31
|
+
lib/thrift/processor.rb
|
32
|
+
lib/thrift/protocol.rb
|
33
|
+
lib/thrift/protocol/binaryprotocol.rb
|
34
|
+
lib/thrift/protocol/binaryprotocolaccelerated.rb
|
35
|
+
lib/thrift/protocol/tbinaryprotocol.rb
|
36
|
+
lib/thrift/protocol/tprotocol.rb
|
37
|
+
lib/thrift/serializer.rb
|
38
|
+
lib/thrift/server.rb
|
39
|
+
lib/thrift/server/httpserver.rb
|
40
|
+
lib/thrift/server/nonblockingserver.rb
|
41
|
+
lib/thrift/server/thttpserver.rb
|
42
|
+
lib/thrift/server/tserver.rb
|
43
|
+
lib/thrift/struct.rb
|
44
|
+
lib/thrift/thrift.rb
|
45
|
+
lib/thrift/transport.rb
|
46
|
+
lib/thrift/transport/httpclient.rb
|
47
|
+
lib/thrift/transport/socket.rb
|
48
|
+
lib/thrift/transport/thttpclient.rb
|
49
|
+
lib/thrift/transport/tsocket.rb
|
50
|
+
lib/thrift/transport/ttransport.rb
|
51
|
+
lib/thrift/transport/unixsocket.rb
|
52
|
+
lib/thrift/types.rb
|
53
|
+
setup.rb
|
54
|
+
spec/ThriftSpec.thrift
|
55
|
+
spec/backwards_compatibility_spec.rb
|
56
|
+
spec/binaryprotocol_spec.rb
|
57
|
+
spec/binaryprotocol_spec_shared.rb
|
58
|
+
spec/binaryprotocolaccelerated_spec.rb
|
59
|
+
spec/client_spec.rb
|
60
|
+
spec/deprecation_spec.rb
|
61
|
+
spec/exception_spec.rb
|
62
|
+
spec/gen-rb/NonblockingService.rb
|
63
|
+
spec/gen-rb/ThriftSpec_constants.rb
|
64
|
+
spec/gen-rb/ThriftSpec_types.rb
|
65
|
+
spec/httpclient_spec.rb
|
66
|
+
spec/httpserver_spec.rb
|
67
|
+
spec/nonblockingserver_spec.rb
|
68
|
+
spec/processor_spec.rb
|
69
|
+
spec/protocol_spec.rb
|
70
|
+
spec/serializer_spec.rb
|
71
|
+
spec/server_spec.rb
|
72
|
+
spec/socket_spec.rb
|
73
|
+
spec/socket_spec_shared.rb
|
74
|
+
spec/spec_helper.rb
|
75
|
+
spec/struct_spec.rb
|
76
|
+
spec/transport_spec.rb
|
77
|
+
spec/types_spec.rb
|
78
|
+
spec/unixsocket_spec.rb
|
data/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Thrift Ruby Software Library
|
2
|
+
by Kevin Ballard, Kevin Clark, Mark Slee
|
3
|
+
http://incubator.apache.org/thrift/
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Thrift is a strongly-typed language-agnostic RPC system.
|
8
|
+
This library is the ruby implementation for both clients and servers.
|
9
|
+
|
10
|
+
== INSTALL:
|
11
|
+
|
12
|
+
$ gem install thrift
|
13
|
+
|
14
|
+
== CAVEATS:
|
15
|
+
|
16
|
+
This library provides the client and server implementations of thrift.
|
17
|
+
It does <em>not</em> provide the compiler for the .thrift files. To compile
|
18
|
+
.thrift files into language-specific implementations, please download the full
|
19
|
+
thrift software package.
|
20
|
+
|
21
|
+
== USAGE:
|
22
|
+
|
23
|
+
This section should get written by someone with the time and inclination.
|
24
|
+
In the meantime, look at existing code, such as the benchmark or the tutorial
|
25
|
+
in the full thrift distribution.
|
26
|
+
|
27
|
+
== LICENSE:
|
28
|
+
|
29
|
+
Thrift is distributed under the Apache Software License.
|
30
|
+
Please see the included LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#
|
2
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
# or more contributor license agreements. See the NOTICE file
|
4
|
+
# distributed with this work for additional information
|
5
|
+
# regarding copyright ownership. The ASF licenses this file
|
6
|
+
# to you under the Apache License, Version 2.0 (the
|
7
|
+
# "License"); you may not use this file except in compliance
|
8
|
+
# with the License. You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing,
|
13
|
+
# software distributed under the License is distributed on an
|
14
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
+
# KIND, either express or implied. See the License for the
|
16
|
+
# specific language governing permissions and limitations
|
17
|
+
# under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'rubygems'
|
21
|
+
require 'rake'
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
|
24
|
+
THRIFT = '../../compiler/cpp/thrift'
|
25
|
+
|
26
|
+
task :default => [:spec]
|
27
|
+
|
28
|
+
task :spec => [:'gen-rb', :realspec]
|
29
|
+
|
30
|
+
Spec::Rake::SpecTask.new(:realspec) do |t|
|
31
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
32
|
+
t.spec_opts = ['--color']
|
33
|
+
end
|
34
|
+
|
35
|
+
Spec::Rake::SpecTask.new(:'spec:rcov') do |t|
|
36
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
37
|
+
t.spec_opts = ['--color']
|
38
|
+
t.rcov = true
|
39
|
+
t.rcov_opts = ['--exclude', '^spec,/gems/']
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Run the compiler tests (requires full thrift checkout)'
|
43
|
+
task :test do
|
44
|
+
# ensure this is a full thrift checkout and not a tarball of the ruby libs
|
45
|
+
cmd = 'head -1 ../../README 2>/dev/null | grep Thrift >/dev/null 2>/dev/null'
|
46
|
+
system(cmd) or fail "rake test requires a full thrift checkout"
|
47
|
+
sh 'make', '-C', File.dirname(__FILE__) + "/../../test/rb", "check"
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Compile the .thrift files for the specs'
|
51
|
+
task :'gen-rb' => [:'gen-rb:spec', :'gen-rb:benchmark', :'gen-rb:debug_proto']
|
52
|
+
|
53
|
+
namespace :'gen-rb' do
|
54
|
+
task :'spec' do
|
55
|
+
dir = File.dirname(__FILE__) + '/spec'
|
56
|
+
sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/ThriftSpec.thrift"
|
57
|
+
end
|
58
|
+
|
59
|
+
task :'benchmark' do
|
60
|
+
dir = File.dirname(__FILE__) + '/benchmark'
|
61
|
+
sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/Benchmark.thrift"
|
62
|
+
end
|
63
|
+
|
64
|
+
task :'debug_proto' do
|
65
|
+
sh "mkdir", "-p", "debug_proto_test"
|
66
|
+
sh THRIFT, '--gen', 'rb', "-o", "debug_proto_test", "../../test/DebugProtoTest.thrift"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc 'Run benchmarking of NonblockingServer'
|
71
|
+
task :benchmark do
|
72
|
+
ruby 'benchmark/benchmark.rb'
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
begin
|
77
|
+
require 'echoe'
|
78
|
+
|
79
|
+
Echoe.new('thrift') do |p|
|
80
|
+
p.author = ['Kevin Ballard', 'Kevin Clark', 'Mark Slee', 'Evan Weaver']
|
81
|
+
p.project = "fauna"
|
82
|
+
p.summary = "Ruby libraries for Thrift (a language-agnostic RPC system)"
|
83
|
+
p.include_rakefile = true
|
84
|
+
p.url = "http://blog.evanweaver.com/files/doc/fauna/thrift/"
|
85
|
+
p.docs_host = "blog.evanweaver.com:~/www/bax/public/files/doc/"
|
86
|
+
end
|
87
|
+
|
88
|
+
task :install => [:check_site_lib]
|
89
|
+
|
90
|
+
require 'rbconfig'
|
91
|
+
task :check_site_lib do
|
92
|
+
file = File.join(Config::CONFIG['sitelibdir'], 'thrift')
|
93
|
+
fail "Thrift is already installed in site_ruby: #{file}*\nPlease remove it if you want to continue." if File.exist?(file)
|
94
|
+
end
|
95
|
+
rescue LoadError
|
96
|
+
[:install, :package].each do |t|
|
97
|
+
desc "Stub for #{t}"
|
98
|
+
task t do
|
99
|
+
fail "The Echoe gem is required for this task"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
require 'thrift'
|
4
|
+
require 'thrift/server/nonblockingserver'
|
5
|
+
require 'thrift/transport/unixsocket'
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
HOST = '127.0.0.1'
|
9
|
+
PORT = 42587
|
10
|
+
|
11
|
+
###############
|
12
|
+
## Server
|
13
|
+
###############
|
14
|
+
|
15
|
+
class Server
|
16
|
+
attr_accessor :serverclass
|
17
|
+
attr_accessor :interpreter
|
18
|
+
attr_accessor :host
|
19
|
+
attr_accessor :port
|
20
|
+
|
21
|
+
def initialize(opts)
|
22
|
+
@serverclass = opts.fetch(:class, Thrift::NonblockingServer)
|
23
|
+
@interpreter = opts.fetch(:interpreter, "ruby")
|
24
|
+
@host = opts.fetch(:host, ::HOST)
|
25
|
+
@port = opts.fetch(:port, ::PORT)
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
return if @serverclass == Object
|
30
|
+
args = (File.basename(@interpreter) == "jruby" ? "-J-server" : "")
|
31
|
+
@pipe = IO.popen("#{@interpreter} #{args} #{File.dirname(__FILE__)}/server.rb #{@host} #{@port} #{@serverclass.name}", "r+")
|
32
|
+
Marshal.load(@pipe) # wait until the server has started
|
33
|
+
sleep 0.4 # give the server time to actually start spawning sockets
|
34
|
+
end
|
35
|
+
|
36
|
+
def shutdown
|
37
|
+
return unless @pipe
|
38
|
+
Marshal.dump(:shutdown, @pipe)
|
39
|
+
begin
|
40
|
+
@pipe.read(10) # block until the server shuts down
|
41
|
+
rescue EOFError
|
42
|
+
end
|
43
|
+
@pipe.close
|
44
|
+
@pipe = nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class BenchmarkManager
|
49
|
+
def initialize(opts, server)
|
50
|
+
@socket = opts.fetch(:socket) do
|
51
|
+
@host = opts.fetch(:host, 'localhost')
|
52
|
+
@port = opts.fetch(:port)
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
@num_processes = opts.fetch(:num_processes, 40)
|
56
|
+
@clients_per_process = opts.fetch(:clients_per_process, 10)
|
57
|
+
@calls_per_client = opts.fetch(:calls_per_client, 50)
|
58
|
+
@interpreter = opts.fetch(:interpreter, "ruby")
|
59
|
+
@server = server
|
60
|
+
@log_exceptions = opts.fetch(:log_exceptions, false)
|
61
|
+
end
|
62
|
+
|
63
|
+
def run
|
64
|
+
@pool = []
|
65
|
+
@benchmark_start = Time.now
|
66
|
+
puts "Spawning benchmark processes..."
|
67
|
+
@num_processes.times do
|
68
|
+
spawn
|
69
|
+
sleep 0.02 # space out spawns
|
70
|
+
end
|
71
|
+
collect_output
|
72
|
+
@benchmark_end = Time.now # we know the procs are done here
|
73
|
+
translate_output
|
74
|
+
analyze_output
|
75
|
+
report_output
|
76
|
+
end
|
77
|
+
|
78
|
+
def spawn
|
79
|
+
pipe = IO.popen("#{@interpreter} #{File.dirname(__FILE__)}/client.rb #{"-log-exceptions" if @log_exceptions} #{@host} #{@port} #{@clients_per_process} #{@calls_per_client}")
|
80
|
+
@pool << pipe
|
81
|
+
end
|
82
|
+
|
83
|
+
def socket_class
|
84
|
+
if @socket
|
85
|
+
Thrift::UNIXSocket
|
86
|
+
else
|
87
|
+
Thrift::Socket
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def collect_output
|
92
|
+
puts "Collecting output..."
|
93
|
+
# read from @pool until all sockets are closed
|
94
|
+
@buffers = Hash.new { |h,k| h[k] = '' }
|
95
|
+
until @pool.empty?
|
96
|
+
rd, = select(@pool)
|
97
|
+
next if rd.nil?
|
98
|
+
rd.each do |fd|
|
99
|
+
begin
|
100
|
+
@buffers[fd] << fd.readpartial(4096)
|
101
|
+
rescue EOFError
|
102
|
+
@pool.delete fd
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def translate_output
|
109
|
+
puts "Translating output..."
|
110
|
+
@output = []
|
111
|
+
@buffers.each do |fd, buffer|
|
112
|
+
strio = StringIO.new(buffer)
|
113
|
+
logs = []
|
114
|
+
begin
|
115
|
+
loop do
|
116
|
+
logs << Marshal.load(strio)
|
117
|
+
end
|
118
|
+
rescue EOFError
|
119
|
+
@output << logs
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def analyze_output
|
125
|
+
puts "Analyzing output..."
|
126
|
+
call_times = []
|
127
|
+
client_times = []
|
128
|
+
connection_failures = []
|
129
|
+
connection_errors = []
|
130
|
+
shortest_call = 0
|
131
|
+
shortest_client = 0
|
132
|
+
longest_call = 0
|
133
|
+
longest_client = 0
|
134
|
+
@output.each do |logs|
|
135
|
+
cur_call, cur_client = nil
|
136
|
+
logs.each do |tok, time|
|
137
|
+
case tok
|
138
|
+
when :start
|
139
|
+
cur_client = time
|
140
|
+
when :call_start
|
141
|
+
cur_call = time
|
142
|
+
when :call_end
|
143
|
+
delta = time - cur_call
|
144
|
+
call_times << delta
|
145
|
+
longest_call = delta unless longest_call > delta
|
146
|
+
shortest_call = delta if shortest_call == 0 or delta < shortest_call
|
147
|
+
cur_call = nil
|
148
|
+
when :end
|
149
|
+
delta = time - cur_client
|
150
|
+
client_times << delta
|
151
|
+
longest_client = delta unless longest_client > delta
|
152
|
+
shortest_client = delta if shortest_client == 0 or delta < shortest_client
|
153
|
+
cur_client = nil
|
154
|
+
when :connection_failure
|
155
|
+
connection_failures << time
|
156
|
+
when :connection_error
|
157
|
+
connection_errors << time
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
@report = {}
|
162
|
+
@report[:total_calls] = call_times.inject(0.0) { |a,t| a += t }
|
163
|
+
@report[:avg_calls] = @report[:total_calls] / call_times.size
|
164
|
+
@report[:total_clients] = client_times.inject(0.0) { |a,t| a += t }
|
165
|
+
@report[:avg_clients] = @report[:total_clients] / client_times.size
|
166
|
+
@report[:connection_failures] = connection_failures.size
|
167
|
+
@report[:connection_errors] = connection_errors.size
|
168
|
+
@report[:shortest_call] = shortest_call
|
169
|
+
@report[:shortest_client] = shortest_client
|
170
|
+
@report[:longest_call] = longest_call
|
171
|
+
@report[:longest_client] = longest_client
|
172
|
+
@report[:total_benchmark_time] = @benchmark_end - @benchmark_start
|
173
|
+
@report[:fastthread] = $".include?('fastthread.bundle')
|
174
|
+
end
|
175
|
+
|
176
|
+
def report_output
|
177
|
+
fmt = "%.4f seconds"
|
178
|
+
puts
|
179
|
+
tabulate "%d",
|
180
|
+
[["Server class", "%s"], @server.serverclass == Object ? "" : @server.serverclass],
|
181
|
+
[["Server interpreter", "%s"], @server.interpreter],
|
182
|
+
[["Client interpreter", "%s"], @interpreter],
|
183
|
+
[["Socket class", "%s"], socket_class],
|
184
|
+
["Number of processes", @num_processes],
|
185
|
+
["Clients per process", @clients_per_process],
|
186
|
+
["Calls per client", @calls_per_client],
|
187
|
+
[["Using fastthread", "%s"], @report[:fastthread] ? "yes" : "no"]
|
188
|
+
puts
|
189
|
+
failures = (@report[:connection_failures] > 0)
|
190
|
+
tabulate fmt,
|
191
|
+
[["Connection failures", "%d", [:red, :bold]], @report[:connection_failures]],
|
192
|
+
[["Connection errors", "%d", [:red, :bold]], @report[:connection_errors]],
|
193
|
+
["Average time per call", @report[:avg_calls]],
|
194
|
+
["Average time per client (%d calls)" % @calls_per_client, @report[:avg_clients]],
|
195
|
+
["Total time for all calls", @report[:total_calls]],
|
196
|
+
["Real time for benchmarking", @report[:total_benchmark_time]],
|
197
|
+
["Shortest call time", @report[:shortest_call]],
|
198
|
+
["Longest call time", @report[:longest_call]],
|
199
|
+
["Shortest client time (%d calls)" % @calls_per_client, @report[:shortest_client]],
|
200
|
+
["Longest client time (%d calls)" % @calls_per_client, @report[:longest_client]]
|
201
|
+
end
|
202
|
+
|
203
|
+
ANSI = {
|
204
|
+
:reset => 0,
|
205
|
+
:bold => 1,
|
206
|
+
:black => 30,
|
207
|
+
:red => 31,
|
208
|
+
:green => 32,
|
209
|
+
:yellow => 33,
|
210
|
+
:blue => 34,
|
211
|
+
:magenta => 35,
|
212
|
+
:cyan => 36,
|
213
|
+
:white => 37
|
214
|
+
}
|
215
|
+
|
216
|
+
def tabulate(fmt, *labels_and_values)
|
217
|
+
labels = labels_and_values.map { |(l,)| Array === l ? l.first : l }
|
218
|
+
label_width = labels.inject(0) { |w,l| l.size > w ? l.size : w }
|
219
|
+
labels_and_values.each do |(l,v)|
|
220
|
+
f = fmt
|
221
|
+
l, f, c = l if Array === l
|
222
|
+
fmtstr = "%-#{label_width+1}s #{f}"
|
223
|
+
if STDOUT.tty? and c and v.to_i > 0
|
224
|
+
fmtstr = "\e[#{[*c].map { |x| ANSI[x] } * ";"}m" + fmtstr + "\e[#{ANSI[:reset]}m"
|
225
|
+
end
|
226
|
+
puts fmtstr % [l+":", v]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def resolve_const(const)
|
232
|
+
const and const.split('::').inject(Object) { |k,c| k.const_get(c) }
|
233
|
+
end
|
234
|
+
|
235
|
+
puts "Starting server..."
|
236
|
+
args = {}
|
237
|
+
args[:interpreter] = ENV['THRIFT_SERVER_INTERPRETER'] || ENV['THRIFT_INTERPRETER'] || "ruby"
|
238
|
+
args[:class] = resolve_const(ENV['THRIFT_SERVER']) || Thrift::NonblockingServer
|
239
|
+
args[:host] = ENV['THRIFT_HOST'] || HOST
|
240
|
+
args[:port] = (ENV['THRIFT_PORT'] || PORT).to_i
|
241
|
+
server = Server.new(args)
|
242
|
+
server.start
|
243
|
+
|
244
|
+
args = {}
|
245
|
+
args[:host] = ENV['THRIFT_HOST'] || HOST
|
246
|
+
args[:port] = (ENV['THRIFT_PORT'] || PORT).to_i
|
247
|
+
args[:num_processes] = (ENV['THRIFT_NUM_PROCESSES'] || 40).to_i
|
248
|
+
args[:clients_per_process] = (ENV['THRIFT_NUM_CLIENTS'] || 5).to_i
|
249
|
+
args[:calls_per_client] = (ENV['THRIFT_NUM_CALLS'] || 50).to_i
|
250
|
+
args[:interpreter] = ENV['THRIFT_CLIENT_INTERPRETER'] || ENV['THRIFT_INTERPRETER'] || "ruby"
|
251
|
+
args[:log_exceptions] = !!ENV['THRIFT_LOG_EXCEPTIONS']
|
252
|
+
BenchmarkManager.new(args, server).run
|
253
|
+
|
254
|
+
server.shutdown
|
data/benchmark/client.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
require 'thrift'
|
3
|
+
require 'thrift/server/nonblockingserver'
|
4
|
+
$:.unshift File.dirname(__FILE__) + "/gen-rb"
|
5
|
+
require 'BenchmarkService'
|
6
|
+
|
7
|
+
class Client
|
8
|
+
def initialize(host, port, clients_per_process, calls_per_client, log_exceptions)
|
9
|
+
@host = host
|
10
|
+
@port = port
|
11
|
+
@clients_per_process = clients_per_process
|
12
|
+
@calls_per_client = calls_per_client
|
13
|
+
@log_exceptions = log_exceptions
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
@clients_per_process.times do
|
18
|
+
socket = Thrift::Socket.new(@host, @port)
|
19
|
+
transport = Thrift::FramedTransport.new(socket)
|
20
|
+
protocol = Thrift::BinaryProtocol.new(transport)
|
21
|
+
client = ThriftBenchmark::BenchmarkService::Client.new(protocol)
|
22
|
+
begin
|
23
|
+
start = Time.now
|
24
|
+
transport.open
|
25
|
+
Marshal.dump [:start, start], STDOUT
|
26
|
+
rescue => e
|
27
|
+
Marshal.dump [:connection_failure, Time.now], STDOUT
|
28
|
+
print_exception e if @log_exceptions
|
29
|
+
else
|
30
|
+
begin
|
31
|
+
@calls_per_client.times do
|
32
|
+
Marshal.dump [:call_start, Time.now], STDOUT
|
33
|
+
client.fibonacci(15)
|
34
|
+
Marshal.dump [:call_end, Time.now], STDOUT
|
35
|
+
end
|
36
|
+
transport.close
|
37
|
+
Marshal.dump [:end, Time.now], STDOUT
|
38
|
+
rescue Thrift::TransportException => e
|
39
|
+
Marshal.dump [:connection_error, Time.now], STDOUT
|
40
|
+
print_exception e if @log_exceptions
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def print_exception(e)
|
47
|
+
STDERR.puts "ERROR: #{e.message}"
|
48
|
+
STDERR.puts "\t#{e.backtrace * "\n\t"}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
log_exceptions = true if ARGV[0] == '-log-exceptions' and ARGV.shift
|
53
|
+
|
54
|
+
host, port, clients_per_process, calls_per_client = ARGV
|
55
|
+
|
56
|
+
Client.new(host, port.to_i, clients_per_process.to_i, calls_per_client.to_i, log_exceptions).run
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'thrift'
|
8
|
+
require 'thrift/protocol'
|
9
|
+
require File.dirname(__FILE__) + '/Benchmark_types'
|
10
|
+
|
11
|
+
module ThriftBenchmark
|
12
|
+
module BenchmarkService
|
13
|
+
class Client
|
14
|
+
include ::Thrift::Client
|
15
|
+
|
16
|
+
def fibonacci(n)
|
17
|
+
send_fibonacci(n)
|
18
|
+
return recv_fibonacci()
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_fibonacci(n)
|
22
|
+
send_message('fibonacci', Fibonacci_args, :n => n)
|
23
|
+
end
|
24
|
+
|
25
|
+
def recv_fibonacci()
|
26
|
+
result = receive_message(Fibonacci_result)
|
27
|
+
return result.success unless result.success.nil?
|
28
|
+
raise Thrift::ApplicationException.new(Thrift::ApplicationException::MISSING_RESULT, 'fibonacci failed: unknown result')
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class Processor
|
34
|
+
include ::Thrift::Processor
|
35
|
+
|
36
|
+
def process_fibonacci(seqid, iprot, oprot)
|
37
|
+
args = read_args(iprot, Fibonacci_args)
|
38
|
+
result = Fibonacci_result.new()
|
39
|
+
result.success = @handler.fibonacci(args.n)
|
40
|
+
write_result(result, oprot, 'fibonacci', seqid)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# HELPER FUNCTIONS AND STRUCTURES
|
46
|
+
|
47
|
+
class Fibonacci_args
|
48
|
+
include ::Thrift::Struct
|
49
|
+
N = 1
|
50
|
+
|
51
|
+
Thrift::Struct.field_accessor self, :n
|
52
|
+
FIELDS = {
|
53
|
+
N => {:type => Thrift::Types::BYTE, :name => 'n'}
|
54
|
+
}
|
55
|
+
|
56
|
+
def struct_fields; FIELDS; end
|
57
|
+
|
58
|
+
def validate
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
class Fibonacci_result
|
64
|
+
include ::Thrift::Struct
|
65
|
+
SUCCESS = 0
|
66
|
+
|
67
|
+
Thrift::Struct.field_accessor self, :success
|
68
|
+
FIELDS = {
|
69
|
+
SUCCESS => {:type => Thrift::Types::I32, :name => 'success'}
|
70
|
+
}
|
71
|
+
|
72
|
+
def struct_fields; FIELDS; end
|
73
|
+
|
74
|
+
def validate
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|