@@ -43,14 +43,23 @@ GrpcAsyncSegmentReporterClient::GrpcAsyncSegmentReporterClient(
4343 AsyncStreamFactory<TracerRequestType, TracerResponseType>& factory,
4444 std::shared_ptr<grpc::ChannelCredentials> cred, std::string address,
4545 std::string token)
46- : token_(token), address_(address), factory_(factory), cq_(cq) {
47- stub_ = std::make_unique<TracerStubImpl>(grpc::CreateChannel (address, cred));
48- stream_ = factory_.create (this );
49- stream_->startStream ();
46+ : token_(token),
47+ factory_ (factory),
48+ cq_(cq),
49+ channel_(grpc::CreateChannel(address, cred)) {
50+ stub_ = std::make_unique<TracerStubImpl>(channel_);
51+ startStream ();
5052}
5153
5254void GrpcAsyncSegmentReporterClient::sendMessage (TracerRequestType message) {
53- GPR_ASSERT (stream_ != nullptr );
55+ if (!stream_) {
56+ drained_messages_.emplace (message);
57+ gpr_log (GPR_INFO,
58+ " No active stream, inserted message into draining message queue. "
59+ " pending message size: %ld" ,
60+ drained_messages_.size ());
61+ return ;
62+ }
5463 stream_->sendMessage (message);
5564}
5665
@@ -64,16 +73,45 @@ GrpcAsyncSegmentReporterClient::createWriter(grpc::ClientContext* ctx,
6473 return stub_->createWriter (ctx, response, cq_, tag);
6574}
6675
76+ void GrpcAsyncSegmentReporterClient::startStream () {
77+ resetStream ();
78+
79+ // Try to establish connection.
80+ channel_->GetState (true );
81+ stream_ = factory_.create (this , drained_messages_);
82+ stream_->startStream ();
83+ }
84+
85+ void GrpcAsyncSegmentReporterClient::drainPendingMessages (
86+ std::queue<TracerRequestType>& pending_messages) {
87+ const auto pending_messages_size = pending_messages.size ();
88+ while (!pending_messages.empty ()) {
89+ auto msg = pending_messages.front ();
90+ pending_messages.pop ();
91+ drained_messages_.emplace (msg);
92+ }
93+ gpr_log (GPR_INFO, " %ld pending messages drained." , pending_messages_size);
94+ }
95+
6796GrpcAsyncSegmentReporterStream::GrpcAsyncSegmentReporterStream (
68- AsyncClient<TracerRequestType, TracerResponseType>* client)
69- : client_(client) {}
97+ AsyncClient<TracerRequestType, TracerResponseType>* client,
98+ std::queue<TracerRequestType>& drained_messages)
99+ : client_(client) {
100+ const auto drained_messages_size = drained_messages.size ();
101+ while (!drained_messages.empty ()) {
102+ auto msg = drained_messages.front ();
103+ pending_messages_.emplace (msg);
104+ drained_messages.pop ();
105+ }
106+ gpr_log (GPR_INFO, " %ld drained messages inserted into pending messages." ,
107+ drained_messages_size);
108+ }
70109
71110GrpcAsyncSegmentReporterStream::~GrpcAsyncSegmentReporterStream () {
72111 {
73112 std::unique_lock<std::mutex> lck_ (mux_);
74113 cond_.wait (lck_, [this ] { return pending_messages_.empty (); });
75114 }
76-
77115 ctx_.TryCancel ();
78116 request_writer_->Finish (&status_, toTag (&finish_));
79117}
@@ -132,6 +170,7 @@ bool GrpcAsyncSegmentReporterStream::handleOperation(Operation incoming_op) {
132170 } else if (state_ == Operation::Finished) {
133171 gpr_log (GPR_INFO, " Stream closed with http status: %d" ,
134172 grpcStatusToGenericHttpStatus (status_.error_code ()));
173+ client_->drainPendingMessages (pending_messages_);
135174 if (!status_.ok ()) {
136175 gpr_log (GPR_ERROR, " %s" , status_.error_message ().c_str ());
137176 }
@@ -141,11 +180,13 @@ bool GrpcAsyncSegmentReporterStream::handleOperation(Operation incoming_op) {
141180}
142181
143182AsyncStreamPtr<TracerRequestType> GrpcAsyncSegmentReporterStreamFactory::create (
144- AsyncClient<TracerRequestType, TracerResponseType>* client) {
183+ AsyncClient<TracerRequestType, TracerResponseType>* client,
184+ std::queue<TracerRequestType>& drained_messages) {
145185 if (client == nullptr ) {
146186 return nullptr ;
147187 }
148- return std::make_shared<GrpcAsyncSegmentReporterStream>(client);
188+ return std::make_shared<GrpcAsyncSegmentReporterStream>(client,
189+ drained_messages);
149190}
150191
151192} // namespace cpp2sky
0 commit comments