aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp/qps
diff options
context:
space:
mode:
authorGravatar Vijay Pai <vpai@google.com>2015-06-03 15:39:35 -0700
committerGravatar Vijay Pai <vpai@google.com>2015-06-03 15:39:35 -0700
commit8eedd4a2c69e377d30f5466b985df9159cc48851 (patch)
treecdf29801203e7aa2a820d030ea790c26b076d0e2 /test/cpp/qps
parent9dc5c15b563eae017a782a547d015d328fd015fe (diff)
Context activation for async
Diffstat (limited to 'test/cpp/qps')
-rw-r--r--test/cpp/qps/client_async.cc69
1 files changed, 47 insertions, 22 deletions
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index e4ce93adb4..fbbc19f58d 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -57,15 +57,13 @@
namespace grpc {
namespace testing {
-typedef std::forward_list<grpc_time> deadline_list;
-
class ClientRpcContext {
public:
ClientRpcContext() {}
virtual ~ClientRpcContext() {}
// next state, return false if done. Collect stats when appropriate
virtual bool RunNextState(bool, Histogram* hist) = 0;
- virtual void StartNewClone() = 0;
+ virtual ClientRpcContext* StartNewClone() = 0;
static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); }
static ClientRpcContext* detag(void* t) {
return reinterpret_cast<ClientRpcContext*>(t);
@@ -110,8 +108,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
return ret;
}
- void StartNewClone() GRPC_OVERRIDE {
- new ClientRpcContextUnaryImpl(stub_, req_, start_req_, callback_);
+ ClientRpcContext* StartNewClone() GRPC_OVERRIDE {
+ return new ClientRpcContextUnaryImpl(stub_, req_, start_req_, callback_);
}
private:
@@ -137,12 +135,17 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
response_reader_;
};
+typedef std::forward_list<grpc_time> deadline_list;
+typedef std::forward_list<ClientRpcContext *> context_list;
+
class AsyncClient : public Client {
public:
explicit AsyncClient(const ClientConfig& config,
std::function<ClientRpcContext*(CompletionQueue*, TestService::Stub*,
const SimpleRequest&)> setup_ctx) :
- Client(config), channel_rpc_lock_(config.client_channels()) {
+ Client(config), channel_rpc_lock_(config.client_channels()),
+ max_outstanding_per_channel_(config.outstanding_rpcs_per_channel()),
+ channel_count_(config.client_channels()) {
SetupLoadTest(config, config.async_client_threads());
@@ -167,8 +170,8 @@ class AsyncClient : public Client {
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
- for (auto channel = channels_.begin(); channel != channels_.end();
- channel++) {
+ for (int ch = 0; ch < channel_count_; ch++) {
+ auto channel = channels_[ch];
auto* cq = cli_cqs_[t].get();
t = (t + 1) % cli_cqs_.size();
ClientRpcContext *ctx = setup_ctx(cq, channel->get_stub(), request_);
@@ -177,6 +180,9 @@ class AsyncClient : public Client {
// closed_loop streaming
ctx->Start();
}
+ else {
+ contexts_[ch].push_front(ctx);
+ }
}
}
}
@@ -200,7 +206,12 @@ class AsyncClient : public Client {
deadline = grpc_time_source::now() + std::chrono::seconds(1);
short_deadline = deadline;
} else {
- deadline = *(rpc_deadlines_[thread_idx].begin());
+ if (rpc_deadlines_[thread_idx].empty()) {
+ deadline = grpc_time_source::now() + std::chrono::seconds(1);
+ }
+ else {
+ deadline = *(rpc_deadlines_[thread_idx].begin());
+ }
short_deadline = issue_allowed_[thread_idx] ?
next_issue_[thread_idx] : deadline;
}
@@ -219,37 +230,50 @@ class AsyncClient : public Client {
GPR_ASSERT(false);
break;
}
- if (grpc_time_source::now() > deadline) {
- // we have missed some 1-second deadline, which is too much gpr_log(GPR_INFO, "Missed an RPC deadline, giving up");
- return false;
- }
- if (got_event) {
+ if ((closed_loop_ || !rpc_deadlines_[thread_idx].empty()) &&
+ grpc_time_source::now() > deadline) {
+ // we have missed some 1-second deadline, which is too much gpr_log(GPR_INFO, "Missed an RPC deadline, giving up");
+ return false;
+ }
+ if (got_event) {
ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
if (ctx->RunNextState(ok, histogram) == false) {
// call the callback and then delete it
rpc_deadlines_[thread_idx].erase_after(ctx->deadline_posn());
ctx->RunNextState(ok, histogram);
- ctx->StartNewClone();
+ ClientRpcContext *clone_ctx = ctx->StartNewClone();
delete ctx;
+ if (!closed_loop_) {
+ // Put this in the list of idle contexts for this channel
+
+ }
}
issue_allowed_[thread_idx] = true; // may be ok now even if it hadn't been
}
if (issue_allowed_[thread_idx] &&
grpc_time_source::now() >= next_issue_[thread_idx]) {
- // Attempt to issue
+ // Attempt to issue
bool issued = false;
for (int num_attempts = 0; num_attempts < channel_count_ && !issued;
- num_attempts++, next_channel_[thread_idx] = (next_channel_[thread_idx]+1)%channel_count_) {
+ num_attempts++,
+ next_channel_[thread_idx] =
+ (next_channel_[thread_idx]+1)%channel_count_) {
std::lock_guard<std::mutex>
- g(channel_rpc_lock_[next_channel_[thread_idx]]);
- if (rpcs_outstanding_[next_channel_[thread_idx]] < max_outstanding_per_channel_) {
+ g(channel_rpc_lock_[next_channel_[thread_idx]]);
+ if ((rpcs_outstanding_[next_channel_[thread_idx]] <
+ max_outstanding_per_channel_) &&
+ !contexts_[next_channel_[thread_idx]].empty()) {
+ // Get an idle context from the front of the list
+ auto ctx = contexts_[next_channel_[thread_idx]].begin();
+ contexts_[next_channel_[thread_idx]].pop_front();
// do the work to issue
+ ctx->Start();
rpcs_outstanding_[next_channel_[thread_idx]]++;
issued = true;
}
}
if (!issued)
- issue_allowed_[thread_idx] = false;
+ issue_allowed_[thread_idx] = false;
}
return true;
}
@@ -264,6 +288,7 @@ class AsyncClient : public Client {
std::vector<std::mutex> channel_rpc_lock_;
std::vector<int> rpcs_outstanding_; // per-channel vector
+ std::vector<context_list> contexts_; // per-channel list of idle contexts
int max_outstanding_per_channel_;
int channel_count_;
};
@@ -311,8 +336,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE {
return (this->*next_state_)(ok, hist);
}
- void StartNewClone() GRPC_OVERRIDE {
- new ClientRpcContextStreamingImpl(stub_, req_, start_req_, callback_);
+ ClientRpcContext* StartNewClone() GRPC_OVERRIDE {
+ return new ClientRpcContextStreamingImpl(stub_, req_, start_req_, callback_);
}
void Start() GRPC_OVERRIDE {}
private: