This is an automated email from the ASF dual-hosted git repository.
wwbmmm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new ec11bb39 Support TCP heartbeat of client (#2098)
ec11bb39 is described below
commit ec11bb39400c2c48455c5f1647a8e651efbe1676
Author: Bright Chen <[email protected]>
AuthorDate: Wed Apr 26 15:45:56 2023 +0800
Support TCP heartbeat of client (#2098)
* support TCP heartbeat of client
* optimize keepalive code & add UT
* optimize keepalive code
* fix keepalive UT
* use PLOG instead of LOG
---
src/brpc/input_messenger.cpp | 40 +++++
src/brpc/socket.cpp | 131 +++++++++++++-
src/brpc/socket.h | 25 +++
test/brpc_socket_unittest.cpp | 387 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 575 insertions(+), 8 deletions(-)
diff --git a/src/brpc/input_messenger.cpp b/src/brpc/input_messenger.cpp
index f33e626c..699f080c 100644
--- a/src/brpc/input_messenger.cpp
+++ b/src/brpc/input_messenger.cpp
@@ -53,6 +53,18 @@ DEFINE_bool(log_connection_close, false,
"Print log when remote side closes the connection");
BRPC_VALIDATE_GFLAG(log_connection_close, PassValidate);
+DEFINE_bool(socket_keepalive, false,
+ "Enable keepalive of sockets if this value is true");
+
+DEFINE_int32(socket_keepalive_idle_s, -1,
+ "Set idle time of sockets before keepalive if this value is
positive");
+
+DEFINE_int32(socket_keepalive_interval_s, -1,
+ "Set interval of sockets between keepalives if this value is
positive");
+
+DEFINE_int32(socket_keepalive_count, -1,
+ "Set number of keepalives of sockets before close if this value
is positive");
+
DECLARE_bool(usercode_in_pthread);
DECLARE_uint64(max_body_size);
@@ -474,6 +486,15 @@ int InputMessenger::Create(const butil::EndPoint&
remote_side,
options.user = this;
options.on_edge_triggered_events = OnNewMessages;
options.health_check_interval_s = health_check_interval_s;
+ if (FLAGS_socket_keepalive) {
+ options.keepalive_options = std::make_shared<SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_idle_s
+ = FLAGS_socket_keepalive_idle_s;
+ options.keepalive_options->keepalive_interval_s
+ = FLAGS_socket_keepalive_interval_s;
+ options.keepalive_options->keepalive_count
+ = FLAGS_socket_keepalive_count;
+ }
return Socket::Create(options, id);
}
@@ -489,6 +510,25 @@ int InputMessenger::Create(SocketOptions options,
SocketId* id) {
#endif
options.on_edge_triggered_events = OnNewMessages;
}
+ // Enable keepalive by options or Gflag.
+ // Priority: options > Gflag.
+ if (options.keepalive_options || FLAGS_socket_keepalive) {
+ if (!options.keepalive_options) {
+ options.keepalive_options =
std::make_shared<SocketKeepaliveOptions>();
+ }
+ if (options.keepalive_options->keepalive_idle_s <= 0) {
+ options.keepalive_options->keepalive_idle_s
+ = FLAGS_socket_keepalive_idle_s;
+ }
+ if (options.keepalive_options->keepalive_interval_s <= 0) {
+ options.keepalive_options->keepalive_interval_s
+ = FLAGS_socket_keepalive_interval_s;
+ }
+ if (options.keepalive_options->keepalive_count <= 0) {
+ options.keepalive_options->keepalive_count
+ = FLAGS_socket_keepalive_count;
+ }
+ }
return Socket::Create(options, id);
}
diff --git a/src/brpc/socket.cpp b/src/brpc/socket.cpp
index c603b0ec..259e09ca 100644
--- a/src/brpc/socket.cpp
+++ b/src/brpc/socket.cpp
@@ -557,28 +557,28 @@ int Socket::ResetFileDescriptor(int fd) {
// OK to fail, namely unix domain socket does not support this.
butil::make_no_delay(fd);
if (_tos > 0 &&
- setsockopt(fd, IPPROTO_IP, IP_TOS, &_tos, sizeof(_tos)) < 0) {
- PLOG(FATAL) << "Fail to set tos of fd=" << fd << " to " << _tos;
+ setsockopt(fd, IPPROTO_IP, IP_TOS, &_tos, sizeof(_tos)) != 0) {
+ PLOG(ERROR) << "Fail to set tos of fd=" << fd << " to " << _tos;
}
if (FLAGS_socket_send_buffer_size > 0) {
int buff_size = FLAGS_socket_send_buffer_size;
- socklen_t size = sizeof(buff_size);
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buff_size, size) != 0) {
- PLOG(FATAL) << "Fail to set sndbuf of fd=" << fd << " to "
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buff_size,
sizeof(buff_size)) != 0) {
+ PLOG(ERROR) << "Fail to set sndbuf of fd=" << fd << " to "
<< buff_size;
}
}
if (FLAGS_socket_recv_buffer_size > 0) {
int buff_size = FLAGS_socket_recv_buffer_size;
- socklen_t size = sizeof(buff_size);
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buff_size, size) != 0) {
- PLOG(FATAL) << "Fail to set rcvbuf of fd=" << fd << " to "
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buff_size,
sizeof(buff_size)) != 0) {
+ PLOG(ERROR) << "Fail to set rcvbuf of fd=" << fd << " to "
<< buff_size;
}
}
+ EnableKeepaliveIfNeeded(fd);
+
if (_on_edge_triggered_events) {
if (GetGlobalEventDispatcher(fd).AddConsumer(id(), fd) != 0) {
PLOG(ERROR) << "Fail to add SocketId=" << id()
@@ -590,6 +590,69 @@ int Socket::ResetFileDescriptor(int fd) {
return 0;
}
+void Socket::EnableKeepaliveIfNeeded(int fd) {
+ if (!_keepalive_options) {
+ return;
+ }
+
+ int keepalive = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
+ sizeof(keepalive)) != 0) {
+ PLOG(ERROR) << "Fail to set keepalive of fd=" << fd;
+ return;
+ }
+
+#if defined(OS_LINUX)
+ if (_keepalive_options->keepalive_idle_s > 0) {
+ if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE,
+ &_keepalive_options->keepalive_idle_s,
+ sizeof(_keepalive_options->keepalive_idle_s)) != 0) {
+ PLOG(ERROR) << "Fail to set keepidle of fd=" << fd;
+ }
+ }
+
+ if (_keepalive_options->keepalive_interval_s > 0) {
+ if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL,
+ &_keepalive_options->keepalive_interval_s,
+ sizeof(_keepalive_options->keepalive_interval_s)) != 0)
{
+ PLOG(ERROR) << "Fail to set keepintvl of fd=" << fd;
+ }
+ }
+
+ if (_keepalive_options->keepalive_count > 0) {
+ if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT,
+ &_keepalive_options->keepalive_count,
+ sizeof(_keepalive_options->keepalive_count)) != 0) {
+ PLOG(ERROR) << "Fail to set keepcnt of fd=" << fd;
+ }
+ }
+#elif defined(OS_MACOSX)
+ if (_keepalive_options->keepalive_idle_s > 0) {
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE,
+ &_keepalive_options->keepalive_idle_s,
+ sizeof(_keepalive_options->keepalive_idle_s)) != 0) {
+ PLOG(ERROR) << "Fail to set keepidle of fd=" << fd;
+ }
+ }
+
+ if (_keepalive_options->keepalive_interval_s > 0) {
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL,
+ &_keepalive_options->keepalive_interval_s,
+ sizeof(_keepalive_options->keepalive_interval_s)) != 0)
{
+ PLOG(ERROR) << "Fail to set keepintvl of fd=" << fd;
+ }
+ }
+
+ if (_keepalive_options->keepalive_count > 0) {
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT,
+ &_keepalive_options->keepalive_count,
+ sizeof(_keepalive_options->keepalive_count)) != 0) {
+ PLOG(ERROR) << "Fail to set keepcnt of fd=" << fd;
+ }
+ }
+#endif
+}
+
// SocketId = 32-bit version + 32-bit slot.
// version: from version part of _versioned_nref, must be an EVEN number.
// slot: designated by ResourcePool.
@@ -676,6 +739,7 @@ int Socket::Create(const SocketOptions& options, SocketId*
id) {
}
m->_last_writetime_us.store(cpuwide_now, butil::memory_order_relaxed);
m->_unwritten_bytes.store(0, butil::memory_order_relaxed);
+ m->_keepalive_options = options.keepalive_options;
CHECK(NULL == m->_write_head.load(butil::memory_order_relaxed));
// Must be last one! Internal fields of this Socket may be access
// just after calling ResetFileDescriptor.
@@ -2268,6 +2332,57 @@ void Socket::DebugSocket(std::ostream& os, SocketId id) {
Print(os, ptr->_ssl_session, "\n ");
os << "\n}";
}
+
+ {
+ int keepalive = 0;
+ socklen_t len = sizeof(keepalive);
+ if (getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, &len) == 0) {
+ os << "\nkeepalive=" << keepalive;
+ }
+ }
+
+ {
+ int keepidle = 0;
+ socklen_t len = sizeof(keepidle);
+#if defined(OS_MACOSX)
+ if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepidle, &len) == 0) {
+ os << "\ntcp_keepalive_time=" << keepidle;
+ }
+#elif defined(OS_LINUX)
+ if (getsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &keepidle, &len) == 0) {
+ os << "\ntcp_keepalive_time=" << keepidle;
+ }
+#endif
+ }
+
+ {
+ int keepintvl = 0;
+ socklen_t len = sizeof(keepintvl);
+#if defined(OS_MACOSX)
+ if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, &len) == 0)
{
+ os << "\ntcp_keepalive_intvl=" << keepintvl;
+ }
+#elif defined(OS_LINUX)
+ if (getsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &keepintvl, &len) == 0) {
+ os << "\ntcp_keepalive_intvl=" << keepintvl;
+ }
+#endif
+ }
+
+ {
+ int keepcnt = 0;
+ socklen_t len = sizeof(keepcnt);
+#if defined(OS_MACOSX)
+ if (getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, &len) == 0) {
+ os << "\ntcp_keepalive_probes=" << keepcnt;
+ }
+#elif defined(OS_LINUX)
+ if (getsockopt(fd, SOL_TCP, TCP_KEEPCNT, &keepcnt, &len) == 0) {
+ os << "\ntcp_keepalive_probes=" << keepcnt;
+ }
+#endif
+ }
+
#if defined(OS_MACOSX)
struct tcp_connection_info ti;
socklen_t len = sizeof(ti);
diff --git a/src/brpc/socket.h b/src/brpc/socket.h
index 6f710ee2..cc77168f 100644
--- a/src/brpc/socket.h
+++ b/src/brpc/socket.h
@@ -173,6 +173,20 @@ struct SocketSSLContext {
std::string sni_name; // useful for clients
};
+struct SocketKeepaliveOptions {
+ SocketKeepaliveOptions()
+ : keepalive_idle_s(-1)
+ , keepalive_interval_s(-1)
+ , keepalive_count(-1)
+ {}
+ // Start keeplives after this period.
+ int keepalive_idle_s;
+ // Interval between keepalives.
+ int keepalive_interval_s;
+ // Number of keepalives before death.
+ int keepalive_count;
+};
+
// TODO: Comment fields
struct SocketOptions {
SocketOptions();
@@ -198,6 +212,10 @@ struct SocketOptions {
std::shared_ptr<AppConnect> app_connect;
// The created socket will set parsing_context with this value.
Destroyable* initial_parsing_context;
+
+ // Socket keepalive related options.
+ // Refer to `SocketKeepaliveOptions' for details.
+ std::shared_ptr<SocketKeepaliveOptions> keepalive_options;
};
// Abstractions on reading from and writing into file descriptors.
@@ -612,6 +630,8 @@ friend void DereferenceSocket(Socket*);
int ResetFileDescriptor(int fd);
+ void EnableKeepaliveIfNeeded(int fd);
+
// Wait until nref hits `expected_nref' and reset some internal resources.
int WaitAndReset(int32_t expected_nref);
@@ -873,6 +893,11 @@ private:
butil::atomic<int64_t> _total_streams_unconsumed_size;
butil::atomic<int64_t> _ninflight_app_health_check;
+
+ // Socket keepalive related options.
+ // Refer to `SocketKeepaliveOptions' for details.
+ // non-NULL means that keepalive is on.
+ std::shared_ptr<SocketKeepaliveOptions> _keepalive_options;
};
} // namespace brpc
diff --git a/test/brpc_socket_unittest.cpp b/test/brpc_socket_unittest.cpp
index 1011c397..10ee988c 100644
--- a/test/brpc_socket_unittest.cpp
+++ b/test/brpc_socket_unittest.cpp
@@ -28,6 +28,7 @@
#include "butil/time.h"
#include "butil/macros.h"
#include "butil/fd_utility.h"
+#include <butil/fd_guard.h>
#include "bthread/unstable.h"
#include "bthread/task_control.h"
#include "brpc/socket.h"
@@ -44,6 +45,7 @@
#if defined(OS_MACOSX)
#include <sys/event.h>
#endif
+#include <netinet/tcp.h>
#define CONNECT_IN_KEEPWRITE 1;
@@ -53,6 +55,10 @@ extern TaskControl* g_task_control;
namespace brpc {
DECLARE_int32(health_check_interval);
+DECLARE_bool(socket_keepalive);
+DECLARE_int32(socket_keepalive_idle_s);
+DECLARE_int32(socket_keepalive_interval_s);
+DECLARE_int32(socket_keepalive_count);
}
void EchoProcessHuluRequest(brpc::InputMessageBase* msg_base);
@@ -1016,3 +1022,384 @@ TEST_F(SocketTest, multi_threaded_write_perf) {
ASSERT_EQ((brpc::Socket*)NULL, global_sock);
close(fds[0]);
}
+
+void GetKeepaliveValue(int fd,
+ int& keepalive,
+ int& keepalive_idle,
+ int& keepalive_interval,
+ int& keepalive_count) {
+ {
+ socklen_t len = sizeof(keepalive);
+ ASSERT_EQ(0, getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
&len));
+
+ }
+
+ {
+ socklen_t len = sizeof(keepalive_idle);
+#if defined(OS_MACOSX)
+ ASSERT_EQ(0, getsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE,
&keepalive_idle, &len));
+#elif defined(OS_LINUX)
+ ASSERT_EQ(0, getsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &keepalive_idle,
&len));
+#endif
+ }
+
+ {
+ socklen_t len = sizeof(keepalive_interval);
+#if defined(OS_MACOSX)
+ ASSERT_EQ(0, getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL,
&keepalive_interval, &len));
+#elif defined(OS_LINUX)
+ ASSERT_EQ(0, getsockopt(fd, SOL_TCP, TCP_KEEPINTVL,
&keepalive_interval, &len));
+#endif
+ }
+
+ {
+ socklen_t len = sizeof(keepalive_count);
+#if defined(OS_MACOSX)
+ ASSERT_EQ(0, getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT,
&keepalive_count, &len));
+#elif defined(OS_LINUX)
+ ASSERT_EQ(0, getsockopt(fd, SOL_TCP, TCP_KEEPCNT, &keepalive_count,
&len));
+#endif
+ }
+}
+
+void CheckNoKeepalive(int fd) {
+ int keepalive = -1;
+ socklen_t len = sizeof(keepalive);
+ ASSERT_EQ(0, getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, &len));
+ ASSERT_EQ(0, keepalive);
+}
+
+void CheckKeepalive(int fd,
+ bool expected_keepalive,
+ int expected_keepalive_idle,
+ int expected_keepalive_interval,
+ int expected_keepalive_count) {
+
+ int keepalive = -1;
+ int keepalive_idle = -1;
+ int keepalive_interval = -1;
+ int keepalive_count = -1;
+ GetKeepaliveValue(fd, keepalive, keepalive_idle,
+ keepalive_interval, keepalive_count);
+ if (expected_keepalive) {
+ ASSERT_LT(0, keepalive);
+ } else {
+ ASSERT_EQ(0, keepalive);
+ return;
+ }
+ ASSERT_EQ(expected_keepalive_idle, keepalive_idle);
+ ASSERT_EQ(expected_keepalive_interval, keepalive_interval);
+ ASSERT_EQ(expected_keepalive_count, keepalive_count);
+}
+
+TEST_F(SocketTest, keepalive) {
+ int default_keepalive = 0;
+ int default_keepalive_idle = 0;
+ int default_keepalive_interval = 0;
+ int default_keepalive_count = 0;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ GetKeepaliveValue(sockfd,
+ default_keepalive,
+ default_keepalive_idle,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Disable keepalive.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckNoKeepalive(ptr->fd());
+ }
+
+ int keepalive_idle = 1;
+ int keepalive_interval = 2;
+ int keepalive_count = 2;
+ // Enable keepalive.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ default_keepalive_idle,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive idle.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_idle_s
+ = keepalive_idle;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ keepalive_idle,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive interval.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_interval_s
+ = keepalive_interval;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ default_keepalive_idle,
+ keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive count.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_count
+ = keepalive_count;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ default_keepalive_idle,
+ default_keepalive_interval,
+ keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive idle, interval, count.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_idle_s
+ = keepalive_idle;
+ options.keepalive_options->keepalive_interval_s
+ = keepalive_interval;
+ options.keepalive_options->keepalive_count
+ = keepalive_count;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::Socket::Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ keepalive_idle,
+ keepalive_interval,
+ keepalive_count);
+ }
+}
+
+
+TEST_F(SocketTest, keepalive_input_message) {
+ int default_keepalive = 0;
+ int default_keepalive_idle = 0;
+ int default_keepalive_interval = 0;
+ int default_keepalive_count = 0;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ GetKeepaliveValue(sockfd,
+ default_keepalive,
+ default_keepalive_idle,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Disable keepalive.
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckNoKeepalive(ptr->fd());
+ }
+
+ // Enable keepalive.
+ brpc::FLAGS_socket_keepalive = true;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ default_keepalive_idle,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive idle.
+ brpc::FLAGS_socket_keepalive_idle_s = 10;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ brpc::FLAGS_socket_keepalive_idle_s,
+ default_keepalive_interval,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive idle, interval.
+ brpc::FLAGS_socket_keepalive_interval_s = 10;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ brpc::FLAGS_socket_keepalive_idle_s,
+ brpc::FLAGS_socket_keepalive_interval_s,
+ default_keepalive_count);
+ }
+
+ // Enable keepalive and set keepalive idle, interval, count.
+ brpc::FLAGS_socket_keepalive_count = 10;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ brpc::FLAGS_socket_keepalive_idle_s,
+ brpc::FLAGS_socket_keepalive_interval_s,
+ brpc::FLAGS_socket_keepalive_count);
+ }
+
+ // Options of keepalive set by user have priority over Gflags.
+ int keepalive_idle = 2;
+ int keepalive_interval = 2;
+ int keepalive_count = 2;
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_idle_s
+ = keepalive_idle;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ keepalive_idle,
+ brpc::FLAGS_socket_keepalive_interval_s,
+ brpc::FLAGS_socket_keepalive_count);
+ }
+
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_interval_s
+ = keepalive_interval;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ brpc::FLAGS_socket_keepalive_idle_s,
+ keepalive_interval,
+ brpc::FLAGS_socket_keepalive_count);
+ }
+
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_count
+ = keepalive_count;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ brpc::FLAGS_socket_keepalive_idle_s,
+ brpc::FLAGS_socket_keepalive_interval_s,
+ keepalive_count);
+ }
+
+ {
+ butil::fd_guard sockfd(socket(AF_INET, SOCK_STREAM, 0));
+ brpc::SocketOptions options;
+ options.fd = sockfd;
+ options.keepalive_options =
std::make_shared<brpc::SocketKeepaliveOptions>();
+ options.keepalive_options->keepalive_idle_s
+ = keepalive_idle;
+ options.keepalive_options->keepalive_interval_s
+ = keepalive_interval;
+ options.keepalive_options->keepalive_count
+ = keepalive_count;
+ brpc::SocketId id;
+ ASSERT_EQ(0, brpc::get_or_new_client_side_messenger()
+ ->Create(options, &id));
+ brpc::SocketUniquePtr ptr;
+ ASSERT_EQ(0, brpc::Socket::Address(id, &ptr));
+ CheckKeepalive(ptr->fd(),
+ true,
+ keepalive_idle,
+ keepalive_interval,
+ keepalive_count);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]