|
|
@ -60,7 +60,7 @@ class SynchronousClient |
|
|
|
SetupLoadTest(config, num_threads_); |
|
|
|
SetupLoadTest(config, num_threads_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
virtual ~SynchronousClient(){}; |
|
|
|
virtual ~SynchronousClient() {} |
|
|
|
|
|
|
|
|
|
|
|
virtual bool InitThreadFuncImpl(size_t thread_idx) = 0; |
|
|
|
virtual bool InitThreadFuncImpl(size_t thread_idx) = 0; |
|
|
|
virtual bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) = 0; |
|
|
|
virtual bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) = 0; |
|
|
@ -154,13 +154,7 @@ class SynchronousStreamingClient : public SynchronousClient { |
|
|
|
messages_issued_(num_threads_) { |
|
|
|
messages_issued_(num_threads_) { |
|
|
|
StartThreads(num_threads_); |
|
|
|
StartThreads(num_threads_); |
|
|
|
} |
|
|
|
} |
|
|
|
virtual ~SynchronousStreamingClient() { |
|
|
|
virtual ~SynchronousStreamingClient() {} |
|
|
|
OnAllStreams([](ClientContext* ctx, StreamType* s) -> bool { |
|
|
|
|
|
|
|
// don't log any kind of error since we might have canceled it
|
|
|
|
|
|
|
|
s->Finish().IgnoreError(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
std::vector<grpc::ClientContext> context_; |
|
|
|
std::vector<grpc::ClientContext> context_; |
|
|
@ -192,13 +186,19 @@ class SynchronousStreamingClient : public SynchronousClient { |
|
|
|
context_[thread_idx].~ClientContext(); |
|
|
|
context_[thread_idx].~ClientContext(); |
|
|
|
new (&context_[thread_idx]) ClientContext(); |
|
|
|
new (&context_[thread_idx]) ClientContext(); |
|
|
|
} |
|
|
|
} |
|
|
|
void OnAllStreams(std::function<bool(ClientContext*, StreamType*)> cleaner) { |
|
|
|
|
|
|
|
|
|
|
|
virtual void CleanStream(size_t thread_idx) { |
|
|
|
|
|
|
|
context_[thread_idx].TryCancel(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CleanupAllStreams() { |
|
|
|
std::vector<std::thread> cleanup_threads; |
|
|
|
std::vector<std::thread> cleanup_threads; |
|
|
|
for (size_t i = 0; i < num_threads_; i++) { |
|
|
|
for (size_t i = 0; i < num_threads_; i++) { |
|
|
|
cleanup_threads.emplace_back([this, i, cleaner]() { |
|
|
|
cleanup_threads.emplace_back([this, i] { |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[i]); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[i]); |
|
|
|
|
|
|
|
shutdown_[i].val = true; |
|
|
|
if (stream_[i]) { |
|
|
|
if (stream_[i]) { |
|
|
|
shutdown_[i].val = cleaner(&context_[i], stream_[i].get()); |
|
|
|
CleanStream(i); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
@ -206,13 +206,9 @@ class SynchronousStreamingClient : public SynchronousClient { |
|
|
|
th.join(); |
|
|
|
th.join(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
private: |
|
|
|
void DestroyMultithreading() override final { |
|
|
|
void DestroyMultithreading() override final { |
|
|
|
OnAllStreams([](ClientContext* ctx, StreamType* s) -> bool { |
|
|
|
CleanupAllStreams(); |
|
|
|
ctx->TryCancel(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
EndThreads(); |
|
|
|
EndThreads(); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
@ -224,14 +220,9 @@ class SynchronousStreamingPingPongClient final |
|
|
|
SynchronousStreamingPingPongClient(const ClientConfig& config) |
|
|
|
SynchronousStreamingPingPongClient(const ClientConfig& config) |
|
|
|
: SynchronousStreamingClient(config) {} |
|
|
|
: SynchronousStreamingClient(config) {} |
|
|
|
~SynchronousStreamingPingPongClient() { |
|
|
|
~SynchronousStreamingPingPongClient() { |
|
|
|
OnAllStreams( |
|
|
|
CleanupAllStreams(); |
|
|
|
[](ClientContext* ctx, |
|
|
|
|
|
|
|
grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>* s) -> bool { |
|
|
|
|
|
|
|
s->WritesDone(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
@ -276,6 +267,12 @@ class SynchronousStreamingPingPongClient final |
|
|
|
messages_issued_[thread_idx] = 0; |
|
|
|
messages_issued_[thread_idx] = 0; |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CleanStream(size_t thread_idx) override { |
|
|
|
|
|
|
|
stream_[thread_idx]->WritesDone(); |
|
|
|
|
|
|
|
// Don't log any kind of error since we may have canceled this
|
|
|
|
|
|
|
|
stream_[thread_idx]->Finish().IgnoreError(); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class SynchronousStreamingFromClientClient final |
|
|
|
class SynchronousStreamingFromClientClient final |
|
|
@ -284,13 +281,12 @@ class SynchronousStreamingFromClientClient final |
|
|
|
SynchronousStreamingFromClientClient(const ClientConfig& config) |
|
|
|
SynchronousStreamingFromClientClient(const ClientConfig& config) |
|
|
|
: SynchronousStreamingClient(config), last_issue_(num_threads_) {} |
|
|
|
: SynchronousStreamingClient(config), last_issue_(num_threads_) {} |
|
|
|
~SynchronousStreamingFromClientClient() { |
|
|
|
~SynchronousStreamingFromClientClient() { |
|
|
|
OnAllStreams( |
|
|
|
CleanupAllStreams(); |
|
|
|
[](ClientContext* ctx, grpc::ClientWriter<SimpleRequest>* s) -> bool { |
|
|
|
|
|
|
|
s->WritesDone(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::vector<double> last_issue_; |
|
|
|
|
|
|
|
|
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
@ -330,8 +326,11 @@ class SynchronousStreamingFromClientClient final |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
void CleanStream(size_t thread_idx) override { |
|
|
|
std::vector<double> last_issue_; |
|
|
|
stream_[thread_idx]->WritesDone(); |
|
|
|
|
|
|
|
// Don't log any kind of error since we may have canceled this
|
|
|
|
|
|
|
|
stream_[thread_idx]->Finish().IgnoreError(); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class SynchronousStreamingFromServerClient final |
|
|
|
class SynchronousStreamingFromServerClient final |
|
|
@ -339,6 +338,13 @@ class SynchronousStreamingFromServerClient final |
|
|
|
public: |
|
|
|
public: |
|
|
|
SynchronousStreamingFromServerClient(const ClientConfig& config) |
|
|
|
SynchronousStreamingFromServerClient(const ClientConfig& config) |
|
|
|
: SynchronousStreamingClient(config), last_recv_(num_threads_) {} |
|
|
|
: SynchronousStreamingClient(config), last_recv_(num_threads_) {} |
|
|
|
|
|
|
|
~SynchronousStreamingFromServerClient() { |
|
|
|
|
|
|
|
CleanupAllStreams(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::vector<double> last_recv_; |
|
|
|
|
|
|
|
|
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
@ -351,6 +357,7 @@ class SynchronousStreamingFromServerClient final |
|
|
|
last_recv_[thread_idx] = UsageTimer::Now(); |
|
|
|
last_recv_[thread_idx] = UsageTimer::Now(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) override { |
|
|
|
bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) override { |
|
|
|
GPR_TIMER_SCOPE("SynchronousStreamingFromServerClient::ThreadFunc", 0); |
|
|
|
GPR_TIMER_SCOPE("SynchronousStreamingFromServerClient::ThreadFunc", 0); |
|
|
|
if (stream_[thread_idx]->Read(&responses_[thread_idx])) { |
|
|
|
if (stream_[thread_idx]->Read(&responses_[thread_idx])) { |
|
|
@ -372,8 +379,10 @@ class SynchronousStreamingFromServerClient final |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
void CleanStream(size_t thread_idx) override { |
|
|
|
std::vector<double> last_recv_; |
|
|
|
// Don't log any kind of error since we may have canceled this
|
|
|
|
|
|
|
|
stream_[thread_idx]->Finish().IgnoreError(); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class SynchronousStreamingBothWaysClient final |
|
|
|
class SynchronousStreamingBothWaysClient final |
|
|
@ -383,14 +392,9 @@ class SynchronousStreamingBothWaysClient final |
|
|
|
SynchronousStreamingBothWaysClient(const ClientConfig& config) |
|
|
|
SynchronousStreamingBothWaysClient(const ClientConfig& config) |
|
|
|
: SynchronousStreamingClient(config) {} |
|
|
|
: SynchronousStreamingClient(config) {} |
|
|
|
~SynchronousStreamingBothWaysClient() { |
|
|
|
~SynchronousStreamingBothWaysClient() { |
|
|
|
OnAllStreams( |
|
|
|
CleanupAllStreams(); |
|
|
|
[](ClientContext* ctx, |
|
|
|
|
|
|
|
grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>* s) -> bool { |
|
|
|
|
|
|
|
s->WritesDone(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
bool InitThreadFuncImpl(size_t thread_idx) override { |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
auto* stub = channels_[thread_idx % channels_.size()].get_stub(); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
|
std::lock_guard<std::mutex> l(stream_mu_[thread_idx]); |
|
|
@ -401,10 +405,17 @@ class SynchronousStreamingBothWaysClient final |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) override { |
|
|
|
bool ThreadFuncImpl(HistogramEntry* entry, size_t thread_idx) override { |
|
|
|
// TODO (vjpai): Do this
|
|
|
|
// TODO (vjpai): Do this
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CleanStream(size_t thread_idx) override { |
|
|
|
|
|
|
|
stream_[thread_idx]->WritesDone(); |
|
|
|
|
|
|
|
// Don't log any kind of error since we may have canceled this
|
|
|
|
|
|
|
|
stream_[thread_idx]->Finish().IgnoreError(); |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) { |
|
|
|
std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) { |
|
|
|