| 536 | } |
| 537 | |
| 538 | void KrpcDataStreamRecvr::SenderQueue::ProcessDeferredRpc() { |
| 539 | // Owns the first entry of 'pending_deferred_rpcs_', |
| 540 | std::unique_ptr<TransmitDataCtx> ctx; |
| 541 | Status status; |
| 542 | { |
| 543 | unique_lock<SpinLock> l(lock_); |
| 544 | DCHECK_GT(num_deserialize_tasks_pending_, 0); |
| 545 | --num_deserialize_tasks_pending_; |
| 546 | |
| 547 | if (pending_deferred_rpcs_.empty()) { |
| 548 | // No need to respond to RPCs as it is done in Cancel(). |
| 549 | DCHECK(is_cancelled_); |
| 550 | return; |
| 551 | } |
| 552 | // A sender queue cannot be cancelled if there is any deferred RPC. |
| 553 | DCHECK(!is_cancelled_); |
| 554 | |
| 555 | // Dequeue and process the first entry from 'pending_deferred_rpcs_'. |
| 556 | ctx = DequeuePendingDeferredRpc(); |
| 557 | TRACE_TO(ctx->rpc_context->trace(), "Processing deferred RPC"); |
| 558 | kudu::Slice tuple_offsets; |
| 559 | kudu::Slice tuple_data; |
| 560 | DCHECK_GE(ctx->deserialized_size, 0); |
| 561 | int64_t batch_size = ctx->deserialized_size; |
| 562 | status = UnpackRequest(ctx->request, ctx->rpc_context, &tuple_offsets, &tuple_data); |
| 563 | // Reply with error status if the entry cannot be unpacked. |
| 564 | if (UNLIKELY(!status.ok())) { |
| 565 | MarkErrorStatus(status, l); |
| 566 | recvr_->deferred_rpc_tracker()->Release(ctx->rpc_context->GetTransferSize()); |
| 567 | l.unlock(); |
| 568 | TRACE_TO(ctx->rpc_context->trace(), |
| 569 | "Error unpacking deferred RPC: $0", status.GetDetail()); |
| 570 | DataStreamService::RespondRpc(status, ctx->response, ctx->rpc_context); |
| 571 | return; |
| 572 | } |
| 573 | |
| 574 | DCHECK_GE(pending_deserialized_size_, batch_size); |
| 575 | pending_deserialized_size_ -= batch_size; |
| 576 | |
| 577 | DCHECK(CanEnqueue(batch_size)); |
| 578 | const RowBatchHeaderPB& header = ctx->request->row_batch_header(); |
| 579 | status = AddBatchWork( |
| 580 | batch_size, header, tuple_offsets, tuple_data, &l, ctx->rpc_context); |
| 581 | DCHECK(!status.ok() || !batch_queue_.empty()); |
| 582 | |
| 583 | // Release to MemTracker while still holding the lock to prevent race with Close(). |
| 584 | recvr_->deferred_rpc_tracker()->Release(ctx->rpc_context->GetTransferSize()); |
| 585 | } |
| 586 | |
| 587 | // Responds to the sender to ack the insertion of the row batches. |
| 588 | // No need to hold lock when enqueuing the response. |
| 589 | DataStreamService::RespondRpc(status, ctx->response, ctx->rpc_context); |
| 590 | } |
| 591 | |
| 592 | Status KrpcDataStreamRecvr::SenderQueue::GetBatchSize( |
| 593 | const TransmitDataRequestPB* request, |
no test coverage detected