// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include #include #include namespace DB { namespace { TrackedMppDataPacketPtr serializePacket(const tipb::SelectResponse & response) { auto tracked_packet = std::make_shared(MPPDataPacketV0); tracked_packet->serializeByResponse(response); return tracked_packet; } } // namespace template void MPPTunnelSetBase::sendExecutionSummary(const tipb::SelectResponse & response) { RUNTIME_CHECK(!tunnels.empty()); // for execution summary, only need to send to one tunnel. tunnels[0]->write(serializePacket(response)); } template void MPPTunnelSetBase::write(TrackedMppDataPacketPtr && data, size_t index) { assert(index < tunnels.size()); tunnels[index]->write(std::move(data)); } template void MPPTunnelSetBase::forceWrite(TrackedMppDataPacketPtr && data, size_t index) { assert(index < tunnels.size()); tunnels[index]->forceWrite(std::move(data)); } template void MPPTunnelSetBase::write(tipb::SelectResponse & response, size_t index) { assert(index < tunnels.size()); tunnels[index]->write(serializePacket(response)); } template void MPPTunnelSetBase::forceWrite(tipb::SelectResponse & response, size_t index) { assert(index < tunnels.size()); tunnels[index]->forceWrite(serializePacket(response)); } template WaitResult MPPTunnelSetBase::waitForWritable() const { for (const auto & tunnel : tunnels) { if (auto res = tunnel->waitForWritable(); res != WaitResult::Ready) return res; } return WaitResult::Ready; } template void MPPTunnelSetBase::notifyNextPipelineWriter() const { for (const auto & tunnel : tunnels) { tunnel->notifyNextPipelineWriter(); } } template void MPPTunnelSetBase::registerTunnel(const MPPTaskId & receiver_task_id, const TunnelPtr & tunnel) { RUNTIME_CHECK_MSG( receiver_task_id_to_index_map.find(receiver_task_id) == receiver_task_id_to_index_map.end(), "the tunnel {} has been registered", tunnel->id()); receiver_task_id_to_index_map[receiver_task_id] = tunnels.size(); tunnels.push_back(tunnel); if (!tunnel->isLocal() && !tunnel->isAsync()) { ++external_thread_cnt; } if (tunnel->isLocal()) { ++local_tunnel_cnt; } } template void MPPTunnelSetBase::close(const String & reason, bool wait_sender_finish) { for (auto & tunnel : tunnels) tunnel->close(reason, wait_sender_finish); } template void MPPTunnelSetBase::finishWrite() { for (auto & tunnel : tunnels) { tunnel->writeDone(); } } template typename MPPTunnelSetBase::TunnelPtr MPPTunnelSetBase::getTunnelByReceiverTaskId(const MPPTaskId & id) { auto it = receiver_task_id_to_index_map.find(id); if (it == receiver_task_id_to_index_map.end()) { return nullptr; } return tunnels[it->second]; } template bool MPPTunnelSetBase::isLocal(size_t index) const { assert(getPartitionNum() > index); return getTunnels()[index]->isLocal(); } /// Explicit template instantiations - to avoid code bloat in headers. template class MPPTunnelSetBase; } // namespace DB