Skip to content

Commit c1bdb77

Browse files
youzhiyuanjenrryyou
authored andcommitted
defer_close_second consider last_active_time
1 parent d22fa17 commit c1bdb77

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

docs/cn/client.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,8 +820,9 @@ brpc支持[Streaming RPC](streaming_rpc.md),这是一种应用层的连接,
820820
| Name | Value | Description | Defined At |
821821
| ------------------ | ----- | ---------------------------------------- | ----------------------- |
822822
| defer_close_second | 0 | Defer close of connections for so many seconds even if the connection is not used by anyone. Close immediately for non-positive values | src/brpc/socket_map.cpp |
823+
| defer_close_respect_idle | false | 当 defer_close_second > 0 时,如果连接在最后一个引用释放时已经闲置超过 defer_close_second,则立刻关闭连接(默认关闭以保持兼容) | src/brpc/socket_map.cpp |
823824
824-
设置后引用计数清0时连接并不会立刻被关闭,而是会等待这么多秒再关闭,如果在这段时间内又有channel引用了这个连接,它会恢复正常被使用的状态。不管channel创建析构有多频率,这个选项使得关闭连接的频率有上限。这个选项的副作用是一些fd不会被及时关闭,如果延时被误设为一个大数值,程序占据的fd个数可能会很大。
825+
设置后引用计数清0时连接并不会立刻被关闭,而是会等待这么多秒再关闭,如果在这段时间内又有channel引用了这个连接,它会恢复正常被使用的状态。不管channel创建析构有多频率,这个选项使得关闭连接的频率有上限。这个选项的副作用是一些fd不会被及时关闭,如果延时被误设为一个大数值,程序占据的fd个数可能会很大。开启 -defer_close_respect_idle 后,如果连接在最后一个引用释放时已经闲置超过 defer_close_second,则可能会被关闭。
825826
826827
## 连接的缓冲区大小
827828

docs/en/client.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,9 @@ Another solution is setting gflag -defer_close_second
717717
| Name | Value | Description | Defined At |
718718
| ------------------ | ----- | ---------------------------------------- | ----------------------- |
719719
| defer_close_second | 0 | Defer close of connections for so many seconds even if the connection is not used by anyone. Close immediately for non-positive values | src/brpc/socket_map.cpp |
720+
| defer_close_respect_idle | false | When defer_close_second > 0, close a connection immediately when the last reference is removed and the socket has already been idle for longer than defer_close_second | src/brpc/socket_map.cpp |
720721
721-
After setting, connection is not closed immediately after last referential count, instead it will be closed after so many seconds. If a channel references the connection again during the wait, the connection resumes to normal. No matter how frequent channels are created, this flag limits the frequency of closing connections. Side effect of the flag is that file descriptors are not closed immediately after destroying of channels, if the flag is wrongly set to be large, number of active file descriptors in the process may be large as well.
722+
After setting, connection is not closed immediately after last referential count, instead it will be closed after so many seconds. If a channel references the connection again during the wait, the connection resumes to normal. No matter how frequent channels are created, this flag limits the frequency of closing connections. Side effect of the flag is that file descriptors are not closed immediately after destroying of channels, if the flag is wrongly set to be large, number of active file descriptors in the process may be large as well. When -defer_close_respect_idle is enabled, a connection that has already been idle for longer than defer_close_second may be closed when the last reference is removed.
722723
723724
## Buffer size of connections
724725

src/brpc/socket_map.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ DEFINE_int32(defer_close_second, 0,
4646
"non-positive values.");
4747
BRPC_VALIDATE_GFLAG(defer_close_second, PassValidate);
4848

49+
DEFINE_bool(defer_close_respect_idle, false,
50+
"When defer_close_second > 0, close a connection immediately when "
51+
"the last reference is removed and the socket has already been "
52+
"idle for longer than defer_close_second. Disabled by default for "
53+
"backward compatibility.");
54+
BRPC_VALIDATE_GFLAG(defer_close_respect_idle, PassValidate);
55+
4956
DEFINE_bool(show_socketmap_in_vars, false,
5057
"[DEBUG] Describe SocketMaps in /vars");
5158
BRPC_VALIDATE_GFLAG(show_socketmap_in_vars, PassValidate);
@@ -71,6 +78,7 @@ static void CreateClientSideSocketMap() {
7178
options.socket_creator = new GlobalSocketCreator;
7279
options.idle_timeout_second_dynamic = &FLAGS_idle_timeout_second;
7380
options.defer_close_second_dynamic = &FLAGS_defer_close_second;
81+
options.defer_close_respect_idle_dynamic = &FLAGS_defer_close_respect_idle;
7482
if (socket_map->Init(options) != 0) {
7583
LOG(FATAL) << "Fail to init SocketMap";
7684
exit(1);
@@ -130,7 +138,8 @@ SocketMapOptions::SocketMapOptions()
130138
, idle_timeout_second_dynamic(NULL)
131139
, idle_timeout_second(0)
132140
, defer_close_second_dynamic(NULL)
133-
, defer_close_second(0) {
141+
, defer_close_second(0)
142+
, defer_close_respect_idle_dynamic(NULL) {
134143
}
135144

136145
SocketMap::SocketMap()
@@ -296,15 +305,29 @@ void SocketMap::RemoveInternal(const SocketMapKey& key,
296305
*_options.defer_close_second_dynamic
297306
: _options.defer_close_second;
298307
if (!remove_orphan && defer_close_second > 0) {
299-
// Start count down on this Socket
300-
sc->no_ref_us = butil::cpuwide_time_us();
301-
} else {
302-
Socket* const s = sc->socket;
303-
_map.erase(key);
304-
mu.unlock();
305-
s->ReleaseAdditionalReference(); // release extra ref
306-
ReleaseReference(s);
308+
const int64_t now_us = butil::cpuwide_time_us();
309+
// NOTE: save the gflag which may be reloaded at any time
310+
const bool defer_close_respect_idle = _options.defer_close_respect_idle_dynamic ?
311+
*_options.defer_close_respect_idle_dynamic : false;
312+
if (!defer_close_respect_idle) {
313+
// Start count down on this Socket.
314+
sc->no_ref_us = now_us;
315+
return;
316+
}
317+
const int64_t defer_us = (int64_t)defer_close_second * 1000000L;
318+
if (sc->no_ref_us <= sc->socket->last_active_time_us() + defer_us) {
319+
// When defer_close_respect_idle is enabled, a connection that has
320+
// already been idle for longer than defer_close_second is closed
321+
// immediately.
322+
sc->no_ref_us = now_us;
323+
return;
324+
}
307325
}
326+
Socket* const s = sc->socket;
327+
_map.erase(key);
328+
mu.unlock();
329+
s->ReleaseAdditionalReference(); // release extra ref
330+
ReleaseReference(s);
308331
}
309332
}
310333

src/brpc/socket_map.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ struct SocketMapOptions {
154154
// Default: 0 (disabled)
155155
const int* defer_close_second_dynamic;
156156
int defer_close_second;
157+
158+
// When defer_close_second > 0 and this flag is true, close a connection
159+
// immediately when the last reference is removed and the socket has already
160+
// been idle for longer than defer_close_second.
161+
// If defer_close_respect_idle_dynamic is not NULL, use the dereferenced
162+
// value each time.
163+
// Default: NULL (treated as false)
164+
const bool* defer_close_respect_idle_dynamic;
157165
};
158166

159167
// Share sockets to the same EndPoint.

0 commit comments

Comments
 (0)