diff options
author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2016-04-05 00:30:40 +0200 |
---|---|---|
committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2016-04-05 00:30:40 +0200 |
commit | 6415043781e0b73008b3db539f18354fe776241a (patch) | |
tree | 78fc8db5eb33ac5cdea96b0a743a57c02e9b0109 /src/ruby | |
parent | 1bb17d31cd00d70048c51c99ed5a827ea10389e6 (diff) | |
parent | 1b7c0a2c5cf27d7a77d9c3476fe6406a98ca3d76 (diff) |
Merge branch 'master' of https://github.com/grpc/grpc into gpr_malloc_is_all
Diffstat (limited to 'src/ruby')
38 files changed, 942 insertions, 38 deletions
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 6b7001a489..82b6d313c8 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c index db7cac363a..cba910d832 100644 --- a/src/ruby/ext/grpc/rb_byte_buffer.c +++ b/src/ruby/ext/grpc/rb_byte_buffer.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,21 +50,18 @@ grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) { } VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) { - size_t length = 0; - char *string = NULL; - size_t offset = 0; + VALUE rb_string; grpc_byte_buffer_reader reader; gpr_slice next; if (buffer == NULL) { return Qnil; - } - length = grpc_byte_buffer_length(buffer); - string = xmalloc(length + 1); + rb_string = rb_str_buf_new(grpc_byte_buffer_length(buffer)); grpc_byte_buffer_reader_init(&reader, buffer); while (grpc_byte_buffer_reader_next(&reader, &next) != 0) { - memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next)); - offset += GPR_SLICE_LENGTH(next); + rb_str_cat(rb_string, (const char *) GPR_SLICE_START_PTR(next), + GPR_SLICE_LENGTH(next)); + gpr_slice_unref(next); } - return rb_str_new(string, length); + return rb_string; } diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c index cd0aa6aaf2..dc80d18b45 100644 --- a/src/ruby/ext/grpc/rb_call.c +++ b/src/ruby/ext/grpc/rb_call.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -551,13 +551,26 @@ static void grpc_run_batch_stack_init(run_batch_stack *st, /* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly * cleaned up */ static void grpc_run_batch_stack_cleanup(run_batch_stack *st) { + size_t i = 0; + grpc_metadata_array_destroy(&st->send_metadata); grpc_metadata_array_destroy(&st->send_trailing_metadata); grpc_metadata_array_destroy(&st->recv_metadata); grpc_metadata_array_destroy(&st->recv_trailing_metadata); + if (st->recv_status_details != NULL) { gpr_free(st->recv_status_details); } + + if (st->recv_message != NULL) { + grpc_byte_buffer_destroy(st->recv_message); + } + + for (i = 0; i < st->op_num; i++) { + if (st->ops[i].op == GRPC_OP_SEND_MESSAGE) { + grpc_byte_buffer_destroy(st->ops[i].data.send_message); + } + } } /* grpc_run_batch_stack_fill_ops fills the run_batch_stack ops array from @@ -643,7 +656,6 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) { break; case GRPC_OP_SEND_MESSAGE: rb_struct_aset(result, sym_send_message, Qtrue); - grpc_byte_buffer_destroy(st->ops[i].data.send_message); break; case GRPC_OP_SEND_CLOSE_FROM_CLIENT: rb_struct_aset(result, sym_send_close, Qtrue); diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index 2b978fcdd0..38bf1f7710 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index e1aaa539db..984afad107 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_channel_args.c b/src/ruby/ext/grpc/rb_channel_args.c index 69827cea1c..2ffb8f41da 100644 --- a/src/ruby/ext/grpc/rb_channel_args.c +++ b/src/ruby/ext/grpc/rb_channel_args.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index f649084311..10391bc963 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c index 1eb5a28750..2a2eee190c 100644 --- a/src/ruby/ext/grpc/rb_completion_queue.c +++ b/src/ruby/ext/grpc/rb_completion_queue.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 0f9b18fa21..acb47b0055 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 3bf81af8fb..22ea84c750 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import; typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); extern grpc_server_request_call_type grpc_server_request_call_import; #define grpc_server_request_call grpc_server_request_call_import -typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host); +typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags); extern grpc_server_register_method_type grpc_server_register_method_import; #define grpc_server_register_method grpc_server_register_method_import typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 37cc55a651..96e60c6776 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c index 4ea59b6b27..33b8372850 100644 --- a/src/ruby/ext/grpc/rb_server_credentials.c +++ b/src/ruby/ext/grpc/rb_server_credentials.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016, Google Inc. + * Copyright 2015, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb index 1671ba3550..4e23cd7af2 100644 --- a/src/ruby/lib/grpc.rb +++ b/src/ruby/lib/grpc.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/core/time_consts.rb b/src/ruby/lib/grpc/core/time_consts.rb index c8eae7806b..3b8c2daa07 100644 --- a/src/ruby/lib/grpc/core/time_consts.rb +++ b/src/ruby/lib/grpc/core/time_consts.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 2227ee1f12..1d7588c18d 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index 213176bd48..6b9b785693 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb index 4da9ff086a..98e83a8396 100644 --- a/src/ruby/lib/grpc/generic/client_stub.rb +++ b/src/ruby/lib/grpc/generic/client_stub.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb index 526b2ba5b6..dd90d8d91d 100644 --- a/src/ruby/lib/grpc/generic/rpc_desc.rb +++ b/src/ruby/lib/grpc/generic/rpc_desc.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index b30d19dd2b..4b5578b018 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/grpc.rb b/src/ruby/lib/grpc/grpc.rb index d8a4947494..250f6dd30d 100644 --- a/src/ruby/lib/grpc/grpc.rb +++ b/src/ruby/lib/grpc/grpc.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index ef0876159d..67c6a5d5a1 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/pb/generate_proto_ruby.sh b/src/ruby/pb/generate_proto_ruby.sh index 86c082099d..82dad18ad0 100755 --- a/src/ruby/pb/generate_proto_ruby.sh +++ b/src/ruby/pb/generate_proto_ruby.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -40,11 +40,18 @@ $PROTOC -I src/proto src/proto/grpc/health/v1/health.proto \ --ruby_out=src/ruby/pb \ --plugin=$PLUGIN -$PROTOC -I . test/proto/{messages,test,empty}.proto \ +$PROTOC -I . \ + src/proto/grpc/testing/{messages,test,empty}.proto \ --grpc_out=src/ruby/pb \ --ruby_out=src/ruby/pb \ --plugin=$PLUGIN +$PROTOC -I . \ + src/proto/grpc/testing/{messages,payloads,stats,services,control}.proto \ + --grpc_out=src/ruby/qps \ + --ruby_out=src/ruby/qps \ + --plugin=$PLUGIN + $PROTOC -I src/proto/math src/proto/math/math.proto \ --grpc_out=src/ruby/bin \ --ruby_out=src/ruby/bin \ diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index 9f1ee65c41..f7310d9289 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 684ee80771..2f83e67c52 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb new file mode 100644 index 0000000000..d04f707479 --- /dev/null +++ b/src/ruby/qps/client.rb @@ -0,0 +1,164 @@ +#!/usr/bin/env ruby + +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Worker and worker service implementation + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) +$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) + +require 'grpc' +require 'histogram' +require 'src/proto/grpc/testing/services_services' + +class Poisson + def interarrival + @lambda_recip * (-Math.log(1.0-rand)) + end + def advance + t = @next_time + @next_time += interarrival + t + end + def initialize(lambda) + @lambda_recip = 1.0/lambda + @next_time = Time.now + interarrival + end +end + +class BenchmarkClient + def initialize(config) + opts = {} + if config.security_params + if config.security_params.use_test_ca + certs = load_test_certs + cred = GRPC::Core::ChannelCredentials.new(certs[0]) + else + cred = GRPC::Core::ChannelCredentials.new() + end + if config.security_params.server_host_override + opts[GRPC::Core::Channel::SSL_TARGET] = + config.security_params.server_host_override + end + else + cred = :this_channel_is_insecure + end + @histres = config.histogram_params.resolution + @histmax = config.histogram_params.max_possible + @start_time = Time.now + @histogram = Histogram.new(@histres, @histmax) + @done = false + + gtsr = Grpc::Testing::SimpleRequest + gtpt = Grpc::Testing::PayloadType + gtp = Grpc::Testing::Payload + simple_params = config.payload_config.simple_params + req = gtsr.new(response_type: gtpt::COMPRESSABLE, + response_size: simple_params.resp_size, + payload: gtp.new(type: gtpt::COMPRESSABLE, + body: nulls(simple_params.req_size))) + + (0..config.client_channels-1).each do |chan| + gtbss = Grpc::Testing::BenchmarkService::Stub + st = config.server_targets + stub = gtbss.new(st[chan % st.length], cred, **opts) + (0..config.outstanding_rpcs_per_channel-1).each do |r| + Thread.new { + case config.load_params.load.to_s + when 'closed_loop' + waiter = nil + when 'poisson' + waiter = Poisson.new(config.load_params.poisson.offered_load / + (config.client_channels * + config.outstanding_rpcs_per_channel)) + end + case config.rpc_type + when :UNARY + unary_ping_ponger(req,stub,config,waiter) + when :STREAMING + streaming_ping_ponger(req,stub,config,waiter) + end + } + end + end + end + def wait_to_issue(waiter) + if waiter + delay = waiter.advance-Time.now + sleep delay if delay > 0 + end + end + def unary_ping_ponger(req, stub, config,waiter) + while !@done + wait_to_issue(waiter) + start = Time.now + resp = stub.unary_call(req) + @histogram.add((Time.now-start)*1e9) + end + end + def streaming_ping_ponger(req, stub, config, waiter) + q = EnumeratorQueue.new(self) + resp = stub.streaming_call(q.each_item) + start = Time.now + q.push(req) + resp.each do |r| + @histogram.add((Time.now-start)*1e9) + if !@done + wait_to_issue(waiter) + start = Time.now + q.push(req) + else + q.push(self) + break + end + end + end + def mark(reset) + lat = Grpc::Testing::HistogramData.new( + bucket: @histogram.contents, + min_seen: @histogram.minimum, + max_seen: @histogram.maximum, + sum: @histogram.sum, + sum_of_squares: @histogram.sum_of_squares, + count: @histogram.count + ) + elapsed = Time.now-@start_time + if reset + @start_time = Time.now + @histogram = Histogram.new(@histres, @histmax) + end + Grpc::Testing::ClientStats.new(latencies: lat, time_elapsed: elapsed) + end + def shutdown + @done = true + end +end diff --git a/src/ruby/qps/histogram.rb b/src/ruby/qps/histogram.rb new file mode 100644 index 0000000000..bf7a89ac46 --- /dev/null +++ b/src/ruby/qps/histogram.rb @@ -0,0 +1,88 @@ +#!/usr/bin/env ruby + +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Histogram class for use in performance testing and measurement + +class Histogram + # Determine the bucket index for a given value + # @param {number} value The value to check + # @return {number} The bucket index + def bucket_for(value) + (Math.log(value)/Math.log(@multiplier)).to_i + end + # Initialize an empty histogram + # @param {number} resolution The resolution of the histogram + # @param {number} max_possible The maximum value for the histogram + def initialize(resolution, max_possible) + @resolution=resolution + @max_possible=max_possible + @sum=0 + @sum_of_squares=0 + @multiplier=1+resolution + @count=0 + @min_seen=max_possible + @max_seen=0 + @buckets=Array.new(bucket_for(max_possible)+1, 0) + end + # Add a value to the histogram. This updates all statistics with the new + # value. Those statistics should not be modified except with this function + # @param {number} value The value to add + def add(value) + @sum += value + @sum_of_squares += value * value + @count += 1 + if value < @min_seen + @min_seen = value + end + if value > @max_seen + @max_seen = value + end + @buckets[bucket_for(value)] += 1 + end + def minimum + @min_seen + end + def maximum + @max_seen + end + def sum + @sum + end + def sum_of_squares + @sum_of_squares + end + def count + @count + end + def contents + @buckets + end +end diff --git a/src/ruby/qps/qps-common.rb b/src/ruby/qps/qps-common.rb new file mode 100644 index 0000000000..4119d600b1 --- /dev/null +++ b/src/ruby/qps/qps-common.rb @@ -0,0 +1,76 @@ +#!/usr/bin/env ruby + +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Worker and worker service implementation + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) +$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) + +require 'grpc' + +# produces a string of null chars (\0 aka pack 'x') of length l. +def nulls(l) + fail 'requires #{l} to be +ve' if l < 0 + [].pack('x' * l).force_encoding('ascii-8bit') +end + +# load the test-only certificates +def load_test_certs + this_dir = File.expand_path(File.dirname(__FILE__)) + data_dir = File.join(File.dirname(this_dir), 'spec/testdata') + files = ['ca.pem', 'server1.key', 'server1.pem'] + files.map { |f| File.open(File.join(data_dir, f)).read } +end + +# A EnumeratorQueue wraps a Queue yielding the items added to it via each_item. +class EnumeratorQueue + extend Forwardable + def_delegators :@q, :push + + def initialize(sentinel) + @q = Queue.new + @sentinel = sentinel + end + + def each_item + return enum_for(:each_item) unless block_given? + loop do + r = @q.pop + break if r.equal?(@sentinel) + fail r if r.is_a? Exception + yield r + end + end +end + + diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb new file mode 100644 index 0000000000..26f46a3140 --- /dev/null +++ b/src/ruby/qps/server.rb @@ -0,0 +1,91 @@ +#!/usr/bin/env ruby + +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Worker and worker service implementation + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) +$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) + +require 'grpc' +require 'qps-common' +require 'src/proto/grpc/testing/messages' +require 'src/proto/grpc/testing/services_services' +require 'src/proto/grpc/testing/stats' + +class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service + def unary_call(req, _call) + sr = Grpc::Testing::SimpleResponse + pl = Grpc::Testing::Payload + sr.new(payload: pl.new(body: nulls(req.response_size))) + end + def streaming_call(reqs) + q = EnumeratorQueue.new(self) + Thread.new { + sr = Grpc::Testing::SimpleResponse + pl = Grpc::Testing::Payload + reqs.each do |req| + q.push(sr.new(payload: pl.new(body: nulls(req.response_size)))) + end + q.push(self) + } + q.each_item + end +end + +class BenchmarkServer + def initialize(config, port) + if config.security_params + certs = load_test_certs + cred = GRPC::Core::ServerCredentials.new( + nil, [{private_key: certs[1], cert_chain: certs[2]}], false) + else + cred = :this_port_is_insecure + end + @server = GRPC::RpcServer.new + @port = @server.add_http2_port("0.0.0.0:" + port.to_s, cred) + @server.handle(BenchmarkServiceImpl.new) + @start_time = Time.now + Thread.new { + @server.run + } + end + def mark(reset) + s = Grpc::Testing::ServerStats.new(time_elapsed: + (Time.now-@start_time).to_f) + @start_time = Time.now if reset + s + end + def get_port + @port + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/control.rb b/src/ruby/qps/src/proto/grpc/testing/control.rb new file mode 100644 index 0000000000..d007123f26 --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/control.rb @@ -0,0 +1,129 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: src/proto/grpc/testing/control.proto + +require 'google/protobuf' + +require 'src/proto/grpc/testing/payloads' +require 'src/proto/grpc/testing/stats' +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "grpc.testing.PoissonParams" do + optional :offered_load, :double, 1 + end + add_message "grpc.testing.UniformParams" do + optional :interarrival_lo, :double, 1 + optional :interarrival_hi, :double, 2 + end + add_message "grpc.testing.DeterministicParams" do + optional :offered_load, :double, 1 + end + add_message "grpc.testing.ParetoParams" do + optional :interarrival_base, :double, 1 + optional :alpha, :double, 2 + end + add_message "grpc.testing.ClosedLoopParams" do + end + add_message "grpc.testing.LoadParams" do + oneof :load do + optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" + optional :poisson, :message, 2, "grpc.testing.PoissonParams" + optional :uniform, :message, 3, "grpc.testing.UniformParams" + optional :determ, :message, 4, "grpc.testing.DeterministicParams" + optional :pareto, :message, 5, "grpc.testing.ParetoParams" + end + end + add_message "grpc.testing.SecurityParams" do + optional :use_test_ca, :bool, 1 + optional :server_host_override, :string, 2 + end + add_message "grpc.testing.ClientConfig" do + repeated :server_targets, :string, 1 + optional :client_type, :enum, 2, "grpc.testing.ClientType" + optional :security_params, :message, 3, "grpc.testing.SecurityParams" + optional :outstanding_rpcs_per_channel, :int32, 4 + optional :client_channels, :int32, 5 + optional :async_client_threads, :int32, 7 + optional :rpc_type, :enum, 8, "grpc.testing.RpcType" + optional :load_params, :message, 10, "grpc.testing.LoadParams" + optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" + optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" + repeated :core_list, :int32, 13 + optional :core_limit, :int32, 14 + end + add_message "grpc.testing.ClientStatus" do + optional :stats, :message, 1, "grpc.testing.ClientStats" + end + add_message "grpc.testing.Mark" do + optional :reset, :bool, 1 + end + add_message "grpc.testing.ClientArgs" do + oneof :argtype do + optional :setup, :message, 1, "grpc.testing.ClientConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerConfig" do + optional :server_type, :enum, 1, "grpc.testing.ServerType" + optional :security_params, :message, 2, "grpc.testing.SecurityParams" + optional :port, :int32, 4 + optional :async_server_threads, :int32, 7 + optional :core_limit, :int32, 8 + optional :payload_config, :message, 9, "grpc.testing.PayloadConfig" + repeated :core_list, :int32, 10 + end + add_message "grpc.testing.ServerArgs" do + oneof :argtype do + optional :setup, :message, 1, "grpc.testing.ServerConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerStatus" do + optional :stats, :message, 1, "grpc.testing.ServerStats" + optional :port, :int32, 2 + optional :cores, :int32, 3 + end + add_message "grpc.testing.CoreRequest" do + end + add_message "grpc.testing.CoreResponse" do + optional :cores, :int32, 1 + end + add_message "grpc.testing.Void" do + end + add_enum "grpc.testing.ClientType" do + value :SYNC_CLIENT, 0 + value :ASYNC_CLIENT, 1 + end + add_enum "grpc.testing.ServerType" do + value :SYNC_SERVER, 0 + value :ASYNC_SERVER, 1 + value :ASYNC_GENERIC_SERVER, 2 + end + add_enum "grpc.testing.RpcType" do + value :UNARY, 0 + value :STREAMING, 1 + end +end + +module Grpc + module Testing + PoissonParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PoissonParams").msgclass + UniformParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.UniformParams").msgclass + DeterministicParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.DeterministicParams").msgclass + ParetoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ParetoParams").msgclass + ClosedLoopParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClosedLoopParams").msgclass + LoadParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadParams").msgclass + SecurityParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SecurityParams").msgclass + ClientConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfig").msgclass + ClientStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStatus").msgclass + Mark = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Mark").msgclass + ClientArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientArgs").msgclass + ServerConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerConfig").msgclass + ServerArgs = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerArgs").msgclass + ServerStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStatus").msgclass + CoreRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreRequest").msgclass + CoreResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CoreResponse").msgclass + Void = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Void").msgclass + ClientType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientType").enummodule + ServerType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerType").enummodule + RpcType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.RpcType").enummodule + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/messages.rb b/src/ruby/qps/src/proto/grpc/testing/messages.rb new file mode 100644 index 0000000000..b9c32dbef5 --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/messages.rb @@ -0,0 +1,80 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: src/proto/grpc/testing/messages.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "grpc.testing.Payload" do + optional :type, :enum, 1, "grpc.testing.PayloadType" + optional :body, :bytes, 2 + end + add_message "grpc.testing.EchoStatus" do + optional :code, :int32, 1 + optional :message, :string, 2 + end + add_message "grpc.testing.SimpleRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + optional :response_size, :int32, 2 + optional :payload, :message, 3, "grpc.testing.Payload" + optional :fill_username, :bool, 4 + optional :fill_oauth_scope, :bool, 5 + optional :response_compression, :enum, 6, "grpc.testing.CompressionType" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.SimpleResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :username, :string, 2 + optional :oauth_scope, :string, 3 + end + add_message "grpc.testing.StreamingInputCallRequest" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.StreamingInputCallResponse" do + optional :aggregated_payload_size, :int32, 1 + end + add_message "grpc.testing.ResponseParameters" do + optional :size, :int32, 1 + optional :interval_us, :int32, 2 + end + add_message "grpc.testing.StreamingOutputCallRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" + optional :payload, :message, 3, "grpc.testing.Payload" + optional :response_compression, :enum, 6, "grpc.testing.CompressionType" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.StreamingOutputCallResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.ReconnectInfo" do + optional :passed, :bool, 1 + repeated :backoff_ms, :int32, 2 + end + add_enum "grpc.testing.PayloadType" do + value :COMPRESSABLE, 0 + value :UNCOMPRESSABLE, 1 + value :RANDOM, 2 + end + add_enum "grpc.testing.CompressionType" do + value :NONE, 0 + value :GZIP, 1 + value :DEFLATE, 2 + end +end + +module Grpc + module Testing + Payload = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Payload").msgclass + EchoStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.EchoStatus").msgclass + SimpleRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleRequest").msgclass + SimpleResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleResponse").msgclass + StreamingInputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallRequest").msgclass + StreamingInputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallResponse").msgclass + ResponseParameters = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ResponseParameters").msgclass + StreamingOutputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallRequest").msgclass + StreamingOutputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallResponse").msgclass + ReconnectInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectInfo").msgclass + PayloadType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule + CompressionType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CompressionType").enummodule + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/payloads.rb b/src/ruby/qps/src/proto/grpc/testing/payloads.rb new file mode 100644 index 0000000000..ae8855f685 --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/payloads.rb @@ -0,0 +1,33 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: src/proto/grpc/testing/payloads.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "grpc.testing.ByteBufferParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.SimpleProtoParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.ComplexProtoParams" do + end + add_message "grpc.testing.PayloadConfig" do + oneof :payload do + optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" + optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" + optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" + end + end +end + +module Grpc + module Testing + ByteBufferParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ByteBufferParams").msgclass + SimpleProtoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleProtoParams").msgclass + ComplexProtoParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ComplexProtoParams").msgclass + PayloadConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadConfig").msgclass + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/services.rb b/src/ruby/qps/src/proto/grpc/testing/services.rb new file mode 100644 index 0000000000..b2675c2afe --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/services.rb @@ -0,0 +1,14 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: src/proto/grpc/testing/services.proto + +require 'google/protobuf' + +require 'src/proto/grpc/testing/messages' +require 'src/proto/grpc/testing/control' +Google::Protobuf::DescriptorPool.generated_pool.build do +end + +module Grpc + module Testing + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services.rb b/src/ruby/qps/src/proto/grpc/testing/services_services.rb new file mode 100644 index 0000000000..3fd9f20f47 --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/services_services.rb @@ -0,0 +1,46 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# Source: src/proto/grpc/testing/services.proto for package 'grpc.testing' + +require 'grpc' +require 'src/proto/grpc/testing/services' + +module Grpc + module Testing + module BenchmarkService + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'grpc.testing.BenchmarkService' + + rpc :UnaryCall, SimpleRequest, SimpleResponse + rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse) + end + + Stub = Service.rpc_stub_class + end + module WorkerService + + # TODO: add proto service documentation here + class Service + + include GRPC::GenericService + + self.marshal_class_method = :encode + self.unmarshal_class_method = :decode + self.service_name = 'grpc.testing.WorkerService' + + rpc :RunServer, stream(ServerArgs), stream(ServerStatus) + rpc :RunClient, stream(ClientArgs), stream(ClientStatus) + rpc :CoreCount, CoreRequest, CoreResponse + rpc :QuitWorker, Void, Void + end + + Stub = Service.rpc_stub_class + end + end +end diff --git a/src/ruby/qps/src/proto/grpc/testing/stats.rb b/src/ruby/qps/src/proto/grpc/testing/stats.rb new file mode 100644 index 0000000000..41f75bedf0 --- /dev/null +++ b/src/ruby/qps/src/proto/grpc/testing/stats.rb @@ -0,0 +1,39 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: src/proto/grpc/testing/stats.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build do + add_message "grpc.testing.ServerStats" do + optional :time_elapsed, :double, 1 + optional :time_user, :double, 2 + optional :time_system, :double, 3 + end + add_message "grpc.testing.HistogramParams" do + optional :resolution, :double, 1 + optional :max_possible, :double, 2 + end + add_message "grpc.testing.HistogramData" do + repeated :bucket, :uint32, 1 + optional :min_seen, :double, 2 + optional :max_seen, :double, 3 + optional :sum, :double, 4 + optional :sum_of_squares, :double, 5 + optional :count, :double, 6 + end + add_message "grpc.testing.ClientStats" do + optional :latencies, :message, 1, "grpc.testing.HistogramData" + optional :time_elapsed, :double, 2 + optional :time_user, :double, 3 + optional :time_system, :double, 4 + end +end + +module Grpc + module Testing + ServerStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ServerStats").msgclass + HistogramParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramParams").msgclass + HistogramData = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.HistogramData").msgclass + ClientStats = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientStats").msgclass + end +end diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb new file mode 100755 index 0000000000..7c29204cc2 --- /dev/null +++ b/src/ruby/qps/worker.rb @@ -0,0 +1,128 @@ +#!/usr/bin/env ruby + +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Worker and worker service implementation + +this_dir = File.expand_path(File.dirname(__FILE__)) +lib_dir = File.join(File.dirname(this_dir), 'lib') +$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) +$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) + +require 'grpc' +require 'optparse' +require 'histogram' +require 'etc' +require 'facter' +require 'client' +require 'qps-common' +require 'server' +require 'src/proto/grpc/testing/services_services' + +class WorkerServiceImpl < Grpc::Testing::WorkerService::Service + def cpu_cores + Facter.value('processors')['count'] + end + def run_server(reqs) + q = EnumeratorQueue.new(self) + Thread.new { + bms = '' + gtss = Grpc::Testing::ServerStatus + reqs.each do |req| + case req.argtype.to_s + when 'setup' + bms = BenchmarkServer.new(req.setup, @server_port) + q.push(gtss.new(stats: bms.mark(false), port: bms.get_port)) + when 'mark' + q.push(gtss.new(stats: bms.mark(req.mark.reset), cores: cpu_cores)) + end + end + q.push(self) + bms.stop + } + q.each_item + end + def run_client(reqs) + q = EnumeratorQueue.new(self) + Thread.new { + client = '' + reqs.each do |req| + case req.argtype.to_s + when 'setup' + client = BenchmarkClient.new(req.setup) + q.push(Grpc::Testing::ClientStatus.new(stats: client.mark(false))) + when 'mark' + q.push(Grpc::Testing::ClientStatus.new(stats: + client.mark(req.mark.reset))) + end + end + q.push(self) + client.shutdown + } + q.each_item + end + def core_count(_args, _call) + Grpc::Testing::CoreResponse.new(cores: cpu_cores) + end + def quit_worker(_args, _call) + Thread.new { + sleep 3 + @server.stop + } + Grpc::Testing::Void.new + end + def initialize(s, sp) + @server = s + @server_port = sp + end +end + +def main + options = { + 'driver_port' => 0, + 'server_port' => 0 + } + OptionParser.new do |opts| + opts.banner = 'Usage: [--driver_port <port>] [--server_port <port>]' + opts.on('--driver_port PORT', '<port>') do |v| + options['driver_port'] = v + end + opts.on('--server_port PORT', '<port>') do |v| + options['server_port'] = v + end + end.parse! + s = GRPC::RpcServer.new + s.add_http2_port("0.0.0.0:" + options['driver_port'].to_s, + :this_port_is_insecure) + s.handle(WorkerServiceImpl.new(s, options['server_port'].to_i)) + s.run +end + +main diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 7ef534571f..aedeca272d 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index dfaec6d6ed..e16ba60387 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb index 9bb79bb4ca..5523347f45 100644 --- a/src/ruby/spec/pb/health/checker_spec.rb +++ b/src/ruby/spec/pb/health/checker_spec.rb @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2015, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without |