第 6 章:WorkerPool
本章说明阻塞任务的投递方式,以及请求快照、响应队列、过载拒绝和退出边界。
1. 适合 WorkerPool 的任务
- 数据库和缓存客户端调用
- 文件系统、压缩、图片处理
- 外部 HTTP/RPC 请求
- 会睡眠或等待不可预测锁的代码
2. 完整 Demo
#include <sttnet.h>
#include <chrono>
#include <iostream>
#include <thread>
int main()
{
using namespace stt::network;
using stt::system::ServerSetting;
if(!ServerSetting::blockTerminationSignals())
{
std::cerr << "failed to block termination signals\n";
return 1;
}
HttpServer server;
// 限制等待中的 Worker 任务数;达到上限时,
// STTNet 拒绝新任务,而不是让内存无限增长。
server.setMaxPendingWorkerTasks(4096);
server.setFunction("/slow",
[&server](HttpServerFDHandler &client,
HttpRequestInformation &request) {
// Reactor 回调是非阻塞执行点。数据库调用、
// 文件访问、RPC、sleep 和不可预测的锁等待
// 应放进 WorkerPool,不能阻塞网络事件循环。
server.putTask(
[](HttpServerFDHandler &workerClient,
HttpRequestInformation &workerRequest) {
// client/request 是 STTNet 提供的安全快照。
// 外层回调局部变量的引用在 Worker 执行时可能已经失效。
std::this_thread::sleep_for(std::chrono::milliseconds(200));
const std::string result =
"worker finished for " + workerRequest.loc;
// 服务端 Worker 中,sendText() 会把响应交给
// Reactor;Worker 不直接写 socket/TLS。
return workerClient.sendText(result) ? 1 : -2;
},
client,
request);
// 返回 0 表示:当前处理阶段转入 WorkerPool 继续执行。
// 任务返回 1 后,STTNet 会继续执行下一个已注册阶段。
return 0;
});
// 第二个参数是 WorkerPool 线程数,不是 Reactor 数量。
// 一个 Server 实例使用一个 Reactor 线程推进网络事件。
if(!server.startListen(8082, 4))
{
std::cerr << "failed to listen on port 8082\n";
return 2;
}
std::cout << "WorkerPool demo listening on http://127.0.0.1:8082\n";
ServerSetting::waitForTerminationSignal();
return server.close() ? 0 : 3;
}3. 回调捕获与生命周期
// 外层回调结束后引用可能失效,因此异步任务使用框架提供的快照。
server.putTask([&client, &request] { /* ... */ }, client, request);
// 安全写法使用 STTNet 传给 Worker lambda 的快照参数。
server.putTask([](HttpServerFDHandler &workerClient,
HttpRequestInformation &workerRequest) {
/* ... */
return workerClient.sendText("done") ? 1 : -2;
}, client, request);4. 背压和超时
setMaxPendingWorkerTasks() 限制等待任务数。队列过载时框架会拒绝新任务并增加 worker_task_rejections,而不是无限占用内存。
优雅退出无法强制终止已经开始执行的 C++ 用户任务。数据库、RPC、文件和锁等待任务的运行条件包含有限超时与可终止的返回路径。
5. 运行结果
./build/examples/sttnet_worker_pool
curl -i http://127.0.0.1:8082/slow预期:约 200 ms 后返回
worker finished for /slow,服务仍能同时处理其他连接。