Demo:WorkerPool 阻塞任务
可构建、可运行、可验证,并与仓库 examples 目录中的源码保持一致。
1. 示例内容
完整源码中的关键调用均有中文注释,页面同时给出运行命令、验证方法和可调整参数。
2. 构建与运行
cmake --build build --target sttnet_worker_pool --parallel
./build/examples/sttnet_worker_pool3. 运行结果
curl http://127.0.0.1:8082/slow预期:约 200 毫秒后返回 worker finished。
4. 完整源码
#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;
}