Coverage Report

Created: 2026-07-10 12:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/util/thrift_rpc_helper.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "util/thrift_rpc_helper.h"
19
20
#include <gen_cpp/Types_types.h>
21
#include <glog/logging.h>
22
#include <thrift/Thrift.h>
23
#include <thrift/protocol/TBinaryProtocol.h>
24
#include <thrift/transport/TTransportException.h>
25
// IWYU pragma: no_include <bits/chrono.h>
26
#include <chrono> // IWYU pragma: keep
27
#include <sstream>
28
#include <thread>
29
30
#include "common/status.h"
31
#include "runtime/exec_env.h" // IWYU pragma: keep
32
#include "util/client_cache.h"
33
#include "util/debug_points.h"
34
#include "util/network_util.h"
35
36
namespace apache {
37
namespace thrift {
38
namespace protocol {
39
class TProtocol;
40
} // namespace protocol
41
namespace transport {
42
class TBufferedTransport;
43
class TSocket;
44
class TTransport;
45
} // namespace transport
46
} // namespace thrift
47
} // namespace apache
48
49
namespace doris {
50
51
using apache::thrift::protocol::TProtocol;
52
using apache::thrift::protocol::TBinaryProtocol;
53
using apache::thrift::transport::TSocket;
54
using apache::thrift::transport::TTransport;
55
using apache::thrift::transport::TBufferedTransport;
56
57
ExecEnv* ThriftRpcHelper::_s_exec_env = nullptr;
58
59
7
void ThriftRpcHelper::setup(ExecEnv* exec_env) {
60
7
    _s_exec_env = exec_env;
61
7
}
62
63
template <typename T>
64
Status ThriftRpcHelper::rpc(const std::string& ip, const int32_t port,
65
34.5k
                            std::function<void(ClientConnection<T>&)> callback, int timeout_ms) {
66
34.5k
    return rpc<T>([ip, port]() { return make_network_address(ip, port); }, callback, timeout_ms);
_ZZN5doris15ThriftRpcHelper3rpcINS_21FrontendServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEiENKUlvE_clEv
Line
Count
Source
66
34.5k
    return rpc<T>([ip, port]() { return make_network_address(ip, port); }, callback, timeout_ms);
Unexecuted instantiation: _ZZN5doris15ThriftRpcHelper3rpcINS_20BackendServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEiENKUlvE_clEv
Unexecuted instantiation: _ZZN5doris15ThriftRpcHelper3rpcINS_24TPaloBrokerServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEiENKUlvE_clEv
67
34.5k
}
_ZN5doris15ThriftRpcHelper3rpcINS_21FrontendServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEi
Line
Count
Source
65
34.5k
                            std::function<void(ClientConnection<T>&)> callback, int timeout_ms) {
66
34.5k
    return rpc<T>([ip, port]() { return make_network_address(ip, port); }, callback, timeout_ms);
67
34.5k
}
Unexecuted instantiation: _ZN5doris15ThriftRpcHelper3rpcINS_20BackendServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEi
Unexecuted instantiation: _ZN5doris15ThriftRpcHelper3rpcINS_24TPaloBrokerServiceClientEEENS_6StatusERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiSt8functionIFvRNS_16ClientConnectionIT_EEEEi
68
69
template <typename T>
70
Status ThriftRpcHelper::rpc(std::function<TNetworkAddress()> address_provider,
71
43.3k
                            std::function<void(ClientConnection<T>&)> callback, int timeout_ms) {
72
43.3k
    TNetworkAddress address = address_provider();
73
43.3k
    if (address.hostname.empty() || address.port == 0) {
74
0
        return Status::Error<ErrorCode::SERVICE_UNAVAILABLE>("FE address is not available");
75
0
    }
76
43.3k
    Status status;
77
43.3k
    DBUG_EXECUTE_IF("thriftRpcHelper.rpc.error", { timeout_ms = 30000; });
78
43.3k
    ClientConnection<T> client(_s_exec_env->get_client_cache<T>(), address, timeout_ms, &status);
79
43.3k
    if (!status.ok()) {
80
0
        LOG(WARNING) << "Connect frontend failed, address=" << address << ", status=" << status;
81
0
        return status;
82
0
    }
83
43.3k
    try {
84
43.3k
        try {
85
43.3k
            callback(client);
86
43.3k
        } catch (apache::thrift::transport::TTransportException& e) {
87
0
            LOG(WARNING) << "retrying call frontend service after "
88
0
                         << config::thrift_client_retry_interval_ms << " ms, address=" << address
89
0
                         << ", reason=" << e.what();
90
0
            std::this_thread::sleep_for(
91
0
                    std::chrono::milliseconds(config::thrift_client_retry_interval_ms));
92
0
            TNetworkAddress retry_address = address_provider();
93
0
            if (retry_address.hostname.empty() || retry_address.port == 0) {
94
0
                return Status::Error<ErrorCode::SERVICE_UNAVAILABLE>("FE address is not available");
95
0
            }
96
0
            if (retry_address.hostname != address.hostname || retry_address.port != address.port) {
97
0
                LOG(INFO) << "retrying call frontend service with new address=" << retry_address;
98
0
                Status retry_status;
99
0
                ClientConnection<T> retry_client(_s_exec_env->get_client_cache<T>(), retry_address,
100
0
                                                 timeout_ms, &retry_status);
101
0
                if (!retry_status.ok()) {
102
0
                    LOG(WARNING) << "Connect frontend failed, address=" << retry_address
103
0
                                 << ", status=" << retry_status;
104
0
                    return retry_status;
105
0
                }
106
0
                callback(retry_client);
107
0
            } else {
108
0
                status = client.reopen(timeout_ms);
109
0
                if (!status.ok()) {
110
0
                    LOG(WARNING) << "client reopen failed. address=" << address
111
0
                                 << ", status=" << status;
112
0
                    return status;
113
0
                }
114
0
                callback(client);
115
0
            }
116
0
        }
117
43.3k
    } catch (apache::thrift::TException& e) {
118
0
        LOG(WARNING) << "call frontend service failed, address=" << address
119
0
                     << ", reason=" << e.what();
120
0
        std::this_thread::sleep_for(
121
0
                std::chrono::milliseconds(config::thrift_client_retry_interval_ms * 2));
122
        // just reopen to disable this connection
123
0
        static_cast<void>(client.reopen(timeout_ms));
124
0
        return Status::RpcError("failed to call frontend service, FE address={}:{}, reason: {}",
125
0
                                address.hostname, address.port, e.what());
126
0
    }
127
43.3k
    return Status::OK();
128
43.3k
}
_ZN5doris15ThriftRpcHelper3rpcINS_21FrontendServiceClientEEENS_6StatusESt8functionIFNS_15TNetworkAddressEvEES4_IFvRNS_16ClientConnectionIT_EEEEi
Line
Count
Source
71
43.3k
                            std::function<void(ClientConnection<T>&)> callback, int timeout_ms) {
72
43.3k
    TNetworkAddress address = address_provider();
73
43.3k
    if (address.hostname.empty() || address.port == 0) {
74
0
        return Status::Error<ErrorCode::SERVICE_UNAVAILABLE>("FE address is not available");
75
0
    }
76
43.3k
    Status status;
77
43.3k
    DBUG_EXECUTE_IF("thriftRpcHelper.rpc.error", { timeout_ms = 30000; });
78
43.3k
    ClientConnection<T> client(_s_exec_env->get_client_cache<T>(), address, timeout_ms, &status);
79
43.3k
    if (!status.ok()) {
80
0
        LOG(WARNING) << "Connect frontend failed, address=" << address << ", status=" << status;
81
0
        return status;
82
0
    }
83
43.3k
    try {
84
43.3k
        try {
85
43.3k
            callback(client);
86
43.3k
        } catch (apache::thrift::transport::TTransportException& e) {
87
0
            LOG(WARNING) << "retrying call frontend service after "
88
0
                         << config::thrift_client_retry_interval_ms << " ms, address=" << address
89
0
                         << ", reason=" << e.what();
90
0
            std::this_thread::sleep_for(
91
0
                    std::chrono::milliseconds(config::thrift_client_retry_interval_ms));
92
0
            TNetworkAddress retry_address = address_provider();
93
0
            if (retry_address.hostname.empty() || retry_address.port == 0) {
94
0
                return Status::Error<ErrorCode::SERVICE_UNAVAILABLE>("FE address is not available");
95
0
            }
96
0
            if (retry_address.hostname != address.hostname || retry_address.port != address.port) {
97
0
                LOG(INFO) << "retrying call frontend service with new address=" << retry_address;
98
0
                Status retry_status;
99
0
                ClientConnection<T> retry_client(_s_exec_env->get_client_cache<T>(), retry_address,
100
0
                                                 timeout_ms, &retry_status);
101
0
                if (!retry_status.ok()) {
102
0
                    LOG(WARNING) << "Connect frontend failed, address=" << retry_address
103
0
                                 << ", status=" << retry_status;
104
0
                    return retry_status;
105
0
                }
106
0
                callback(retry_client);
107
0
            } else {
108
0
                status = client.reopen(timeout_ms);
109
0
                if (!status.ok()) {
110
0
                    LOG(WARNING) << "client reopen failed. address=" << address
111
0
                                 << ", status=" << status;
112
0
                    return status;
113
0
                }
114
0
                callback(client);
115
0
            }
116
0
        }
117
43.3k
    } catch (apache::thrift::TException& e) {
118
0
        LOG(WARNING) << "call frontend service failed, address=" << address
119
0
                     << ", reason=" << e.what();
120
0
        std::this_thread::sleep_for(
121
0
                std::chrono::milliseconds(config::thrift_client_retry_interval_ms * 2));
122
        // just reopen to disable this connection
123
0
        static_cast<void>(client.reopen(timeout_ms));
124
0
        return Status::RpcError("failed to call frontend service, FE address={}:{}, reason: {}",
125
0
                                address.hostname, address.port, e.what());
126
0
    }
127
43.3k
    return Status::OK();
128
43.3k
}
Unexecuted instantiation: _ZN5doris15ThriftRpcHelper3rpcINS_20BackendServiceClientEEENS_6StatusESt8functionIFNS_15TNetworkAddressEvEES4_IFvRNS_16ClientConnectionIT_EEEEi
Unexecuted instantiation: _ZN5doris15ThriftRpcHelper3rpcINS_24TPaloBrokerServiceClientEEENS_6StatusESt8functionIFNS_15TNetworkAddressEvEES4_IFvRNS_16ClientConnectionIT_EEEEi
129
130
template Status ThriftRpcHelper::rpc<FrontendServiceClient>(
131
        const std::string& ip, const int32_t port,
132
        std::function<void(ClientConnection<FrontendServiceClient>&)> callback, int timeout_ms);
133
134
template Status ThriftRpcHelper::rpc<FrontendServiceClient>(
135
        std::function<TNetworkAddress()> address_provider,
136
        std::function<void(ClientConnection<FrontendServiceClient>&)> callback, int timeout_ms);
137
138
template Status ThriftRpcHelper::rpc<BackendServiceClient>(
139
        const std::string& ip, const int32_t port,
140
        std::function<void(ClientConnection<BackendServiceClient>&)> callback, int timeout_ms);
141
142
template Status ThriftRpcHelper::rpc<TPaloBrokerServiceClient>(
143
        const std::string& ip, const int32_t port,
144
        std::function<void(ClientConnection<TPaloBrokerServiceClient>&)> callback, int timeout_ms);
145
146
} // namespace doris