forked from ChunelFeng/CGraph
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathE05-HttpServer.cpp
More file actions
121 lines (97 loc) · 3.31 KB
/
Copy pathE05-HttpServer.cpp
File metadata and controls
121 lines (97 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/***************************
@Author: Chunel
@Contact: chunel@foxmail.com
@File: E05-HttpServer.cpp
@Time: 2026/2/15 16:28
@Desc: 本例主要展示,在server端创建n个 pipeline,放入manager中
在被client请求的时候,会从manager 中取出一个,并且执行,然后再放回
***************************/
#include "CGraph.h"
using namespace CGraph;
const static char* EXAMPLE_PARAM_KEY = "/http/server/param_key";
struct HttpParam : public GParam {
CStatus setup() override {
val_ = 0;
return CStatus();
}
int val_ {0};
int loop_ {0};
};
class ReqeustNode : public GNode {
CStatus init() override {
auto status = CGRAPH_CREATE_GPARAM(HttpParam, EXAMPLE_PARAM_KEY);
return status;
}
CStatus run() final {
CGRAPH_ECHO(" ----> enter request node");
return CStatus();
}
};
template<int STEP, int MS>
class ProcessNode : public GNode {
CStatus run() override {
auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(HttpParam, EXAMPLE_PARAM_KEY);
{
CGRAPH_PARAM_WRITE_CODE_BLOCK(param);
CGRAPH_ECHO("process step %d, sleep %d ms, val is %d, loop is %d",
STEP, MS, ++param->val_, ++param->loop_);
}
CGRAPH_SLEEP_MILLISECOND(MS);
return CStatus();
}
};
class ResponseNode : public GNode {
CStatus run() override {
CGRAPH_ECHO(" <---- enter response node");
return CStatus();
}
};
GPipeline* build_pipeline() {
GPipeline* pipeline = GPipelineFactory::create();
GElementPtr a, b, c, d = nullptr;
pipeline->registerGElement<ReqeustNode>(&a, {}, "request");
pipeline->registerGElement<ProcessNode<1, 100>>(&b, {a}, "process_1");
pipeline->registerGElement<ProcessNode<2, 200>>(&c, {a}, "process_2");
pipeline->registerGElement<ResponseNode>(&d, {b, c}, "response");
return pipeline;
}
void mock_client_request(GPipelineManager& manager) {
for (int i = 0; i < 10; i++) {
/**
* 不同的线程,直接调用manger的run,是互斥运行的
* 相当于直接运行 manager中 的pipeline 中的run函数
* 如果并发请求数量,超过 manager中 pipeline数量,则status返回报错。
* 也可以通过 manager.fetch() 和 manager.release() 接口在外部控制pipeline的获取和释放
*/
auto status = manager.run();
if (status.isErr()) {
CGRAPH_ECHO("manager run failed. err info is [%s]", status.getInfo().c_str());
}
CGRAPH_SLEEP_MILLISECOND(10);
}
}
void example_http_server() {
GPipelineManager manager;
const int times = 3;
for (int i = 0; i < times; i++) {
auto pipeline = build_pipeline();
manager.add(pipeline); // 在manger中,加入3个pipeline信息
}
auto status = manager.init(); // 初始化 manager 中所有的pipeline信息
std::vector<std::thread> thds;
for (int i = 0; i < times; i++) {
auto thd = std::thread([&] {
mock_client_request(manager);
});
thds.emplace_back(std::move(thd));
}
for (int i = 0; i < times; i++) {
thds[i].join();
}
manager.destroy();
GPipelineFactory::clear(); // 这里析构所有的pipeline信息
}
int main() {
example_http_server();
return 0;
}