Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/cn/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -820,8 +820,9 @@ brpc支持[Streaming RPC](streaming_rpc.md),这是一种应用层的连接,
| Name | Value | Description | Defined At |
| ------------------ | ----- | ---------------------------------------- | ----------------------- |
| 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 |
| defer_close_respect_idle | false | 当 defer_close_second > 0 时,如果连接在最后一个引用释放时已经闲置超过 defer_close_second,则立刻关闭连接(默认关闭以保持兼容) | src/brpc/socket_map.cpp |

设置后引用计数清0时连接并不会立刻被关闭,而是会等待这么多秒再关闭,如果在这段时间内又有channel引用了这个连接,它会恢复正常被使用的状态。不管channel创建析构有多频率,这个选项使得关闭连接的频率有上限。这个选项的副作用是一些fd不会被及时关闭,如果延时被误设为一个大数值,程序占据的fd个数可能会很大。
设置后引用计数清0时连接并不会立刻被关闭,而是会等待这么多秒再关闭,如果在这段时间内又有channel引用了这个连接,它会恢复正常被使用的状态。不管channel创建析构有多频率,这个选项使得关闭连接的频率有上限。这个选项的副作用是一些fd不会被及时关闭,如果延时被误设为一个大数值,程序占据的fd个数可能会很大。开启 -defer_close_respect_idle 后,如果连接在最后一个引用释放时已经闲置超过 defer_close_second,则可能会被关闭。

## 连接的缓冲区大小

Expand Down
3 changes: 2 additions & 1 deletion docs/en/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -717,8 +717,9 @@ Another solution is setting gflag -defer_close_second
| Name | Value | Description | Defined At |
| ------------------ | ----- | ---------------------------------------- | ----------------------- |
| 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 |
| 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 |

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.
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.

## Buffer size of connections

Expand Down
41 changes: 32 additions & 9 deletions src/brpc/socket_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ DEFINE_int32(defer_close_second, 0,
"non-positive values.");
BRPC_VALIDATE_GFLAG(defer_close_second, PassValidate);

DEFINE_bool(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. Disabled by default for "
"backward compatibility.");
BRPC_VALIDATE_GFLAG(defer_close_respect_idle, PassValidate);

DEFINE_bool(show_socketmap_in_vars, false,
"[DEBUG] Describe SocketMaps in /vars");
BRPC_VALIDATE_GFLAG(show_socketmap_in_vars, PassValidate);
Expand All @@ -71,6 +78,7 @@ static void CreateClientSideSocketMap() {
options.socket_creator = new GlobalSocketCreator;
options.idle_timeout_second_dynamic = &FLAGS_idle_timeout_second;
options.defer_close_second_dynamic = &FLAGS_defer_close_second;
options.defer_close_respect_idle_dynamic = &FLAGS_defer_close_respect_idle;
if (socket_map->Init(options) != 0) {
LOG(FATAL) << "Fail to init SocketMap";
exit(1);
Expand Down Expand Up @@ -130,7 +138,8 @@ SocketMapOptions::SocketMapOptions()
, idle_timeout_second_dynamic(NULL)
, idle_timeout_second(0)
, defer_close_second_dynamic(NULL)
, defer_close_second(0) {
, defer_close_second(0)
, defer_close_respect_idle_dynamic(NULL) {
}

SocketMap::SocketMap()
Expand Down Expand Up @@ -296,15 +305,29 @@ void SocketMap::RemoveInternal(const SocketMapKey& key,
*_options.defer_close_second_dynamic
: _options.defer_close_second;
if (!remove_orphan && defer_close_second > 0) {
// Start count down on this Socket
sc->no_ref_us = butil::cpuwide_time_us();
} else {
Socket* const s = sc->socket;
_map.erase(key);
mu.unlock();
s->ReleaseAdditionalReference(); // release extra ref
ReleaseReference(s);
const int64_t now_us = butil::cpuwide_time_us();
// NOTE: save the gflag which may be reloaded at any time
const bool defer_close_respect_idle = _options.defer_close_respect_idle_dynamic ?
*_options.defer_close_respect_idle_dynamic : false;
if (!defer_close_respect_idle) {
// Start count down on this Socket.
sc->no_ref_us = now_us;
return;
}
const int64_t defer_us = (int64_t)defer_close_second * 1000000L;
if (sc->no_ref_us <= sc->socket->last_active_time_us() + defer_us) {
// When defer_close_respect_idle is enabled, a connection that has
// already been idle for longer than defer_close_second is closed
// immediately.
sc->no_ref_us = now_us;
return;
}
}
Socket* const s = sc->socket;
_map.erase(key);
mu.unlock();
s->ReleaseAdditionalReference(); // release extra ref
ReleaseReference(s);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/brpc/socket_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ struct SocketMapOptions {
// Default: 0 (disabled)
const int* defer_close_second_dynamic;
int defer_close_second;

// When defer_close_second > 0 and this flag is true, close a connection
// immediately when the last reference is removed and the socket has already
// been idle for longer than defer_close_second.
// If defer_close_respect_idle_dynamic is not NULL, use the dereferenced
// value each time.
// Default: NULL (treated as false)
const bool* defer_close_respect_idle_dynamic;
};

// Share sockets to the same EndPoint.
Expand Down
Loading