|
@@ -1,23 +1,28 @@
|
|
-#include <vector>
|
|
|
|
#include <csignal>
|
|
#include <csignal>
|
|
|
|
+#include <vector>
|
|
|
|
|
|
#include "base/utils/string/str_utils.h"
|
|
#include "base/utils/string/str_utils.h"
|
|
#include "fmt/chrono.h"
|
|
#include "fmt/chrono.h"
|
|
|
|
+#include "fmt/format.h"
|
|
#include "gflags/gflags.h"
|
|
#include "gflags/gflags.h"
|
|
-#include "nlohmann/json.hpp"
|
|
|
|
#include "net_io/server/http_server/http_server.h"
|
|
#include "net_io/server/http_server/http_server.h"
|
|
-
|
|
|
|
|
|
+#include "nlohmann/json.hpp"
|
|
|
|
|
|
using namespace lt::net;
|
|
using namespace lt::net;
|
|
using namespace lt;
|
|
using namespace lt;
|
|
using namespace base;
|
|
using namespace base;
|
|
|
|
+using namespace co;
|
|
|
|
|
|
DEFINE_int32(loops, 4, "how many loops use for handle message and io");
|
|
DEFINE_int32(loops, 4, "how many loops use for handle message and io");
|
|
-DEFINE_string(http, "0.0.0.0:5006", "host:port used for http service listen on");
|
|
|
|
|
|
+DEFINE_bool(echo, false, "just echo response without any logic");
|
|
|
|
+DEFINE_bool(coro, false, "using coro context handle request");
|
|
|
|
+DEFINE_string(http,
|
|
|
|
+ "0.0.0.0:5006",
|
|
|
|
+ "host:port used for http service listen on");
|
|
|
|
|
|
-class HttpBenchMarkServer {
|
|
|
|
|
|
+class HttpBenchServer {
|
|
public:
|
|
public:
|
|
- ~HttpBenchMarkServer() {
|
|
|
|
|
|
+ ~HttpBenchServer() {
|
|
LOG(INFO) << __func__ << " close app";
|
|
LOG(INFO) << __func__ << " close app";
|
|
for (auto loop : loops) {
|
|
for (auto loop : loops) {
|
|
delete loop;
|
|
delete loop;
|
|
@@ -26,43 +31,47 @@ public:
|
|
}
|
|
}
|
|
|
|
|
|
void Run() {
|
|
void Run() {
|
|
- main_loop.Start();
|
|
|
|
-
|
|
|
|
|
|
+ json_message["message"] = "Hello, World!";
|
|
|
|
|
|
- int loop_count = std::max(FLAGS_loops, int(std::thread::hardware_concurrency()));
|
|
|
|
|
|
+ int loop_count =
|
|
|
|
+ std::max(FLAGS_loops, int(std::thread::hardware_concurrency()));
|
|
LOG(INFO) << __func__ << " use loop count:" << loop_count;
|
|
LOG(INFO) << __func__ << " use loop count:" << loop_count;
|
|
|
|
|
|
for (int i = 0; i < loop_count; i++) {
|
|
for (int i = 0; i < loop_count; i++) {
|
|
- auto loop = new(base::MessageLoop);
|
|
|
|
- loop->Start();
|
|
|
|
- loops.push_back(loop);
|
|
|
|
|
|
+ loops.push_back(new base::MessageLoop(fmt::format("io_{}", i)));
|
|
|
|
+ loops.back()->Start();
|
|
|
|
+ CoroRunner::RegisteRunner(loops.back());
|
|
}
|
|
}
|
|
|
|
|
|
- http_server.WithIOLoops(loops)
|
|
|
|
- .WithAddress(base::StrUtil::Concat("http://", FLAGS_http))
|
|
|
|
- .ServeAddress([this](const RefHttpRequestCtx& context) {
|
|
|
|
- VLOG(GLOG_VTRACE) << " got Http request from benchmark api";
|
|
|
|
-
|
|
|
|
- const HttpRequest* req = context->Request();
|
|
|
|
- //TODO: response freelist
|
|
|
|
- auto response = HttpResponse::CreateWithCode(200);
|
|
|
|
- response->SetKeepAlive(req->IsKeepAlive());
|
|
|
|
-
|
|
|
|
|
|
+ auto func = [this](const RefHttpRequestCtx& context) {
|
|
|
|
+ const HttpRequest* req = context->Request();
|
|
|
|
+ // TODO: response freelist
|
|
|
|
+ auto response = HttpResponse::CreateWithCode(200);
|
|
|
|
+ response->SetKeepAlive(req->IsKeepAlive());
|
|
|
|
+ if (FLAGS_echo) {
|
|
|
|
+ response->MutableBody() = "echo";
|
|
|
|
+ } else {
|
|
response->InsertHeader("Server", "ltio");
|
|
response->InsertHeader("Server", "ltio");
|
|
auto tm = fmt::gmtime(std::time(nullptr));
|
|
auto tm = fmt::gmtime(std::time(nullptr));
|
|
- response->InsertHeader("Date", fmt::format("{:%a, %d %b %Y %H:%M:%S %Z}", tm));
|
|
|
|
|
|
+ response->InsertHeader("Date",
|
|
|
|
+ fmt::format("{:%a, %d %b %Y %H:%M:%S %Z}", tm));
|
|
if (req->RequestUrl() == "/plaintext") {
|
|
if (req->RequestUrl() == "/plaintext") {
|
|
response->MutableBody() = "Hello, World!";
|
|
response->MutableBody() = "Hello, World!";
|
|
} else if (req->RequestUrl() == "/json") {
|
|
} else if (req->RequestUrl() == "/json") {
|
|
- nlohmann::json json_message;
|
|
|
|
- json_message["message"] = "Hello, World!";
|
|
|
|
- response->MutableBody() = std::move(json_message.dump());
|
|
|
|
response->InsertHeader("Content-Type", "application/json");
|
|
response->InsertHeader("Content-Type", "application/json");
|
|
|
|
+ response->MutableBody() = std::move(json_message.dump());
|
|
}
|
|
}
|
|
- return context->Response(response);
|
|
|
|
- });
|
|
|
|
|
|
+ }
|
|
|
|
+ return context->Response(response);
|
|
|
|
+ };
|
|
|
|
|
|
- main_loop.WaitLoopEnd();
|
|
|
|
|
|
+ handler.reset(FLAGS_coro ? NewHttpCoroHandler(func) : NewHttpHandler(func));
|
|
|
|
+
|
|
|
|
+ // ProfilerStart("perf.out");
|
|
|
|
+ http_server.WithIOLoops(loops)
|
|
|
|
+ .WithAddress(base::StrUtil::Concat("http://", FLAGS_http))
|
|
|
|
+ .ServeAddress(handler.get());
|
|
|
|
+ loops.back()->WaitLoopEnd();
|
|
}
|
|
}
|
|
|
|
|
|
void Stop() {
|
|
void Stop() {
|
|
@@ -71,32 +80,32 @@ public:
|
|
http_server.StopServer(CO_RESUMER);
|
|
http_server.StopServer(CO_RESUMER);
|
|
CO_YIELD;
|
|
CO_YIELD;
|
|
LOG(INFO) << __FUNCTION__ << " stop leave";
|
|
LOG(INFO) << __FUNCTION__ << " stop leave";
|
|
- main_loop.QuitLoop();
|
|
|
|
|
|
+ loops.back()->QuitLoop();
|
|
}
|
|
}
|
|
|
|
|
|
HttpServer http_server;
|
|
HttpServer http_server;
|
|
- //HttpCoroServer http_server;
|
|
|
|
|
|
+ std::unique_ptr<CodecService::Handler> handler;
|
|
base::MessageLoop main_loop;
|
|
base::MessageLoop main_loop;
|
|
|
|
+ nlohmann::json json_message;
|
|
std::vector<base::MessageLoop*> loops;
|
|
std::vector<base::MessageLoop*> loops;
|
|
};
|
|
};
|
|
|
|
|
|
-HttpBenchMarkServer app;
|
|
|
|
|
|
+HttpBenchServer app;
|
|
|
|
|
|
-void signalHandler( int signum ){
|
|
|
|
|
|
+void signalHandler(int signum) {
|
|
LOG(INFO) << "sighandler sig:" << signum;
|
|
LOG(INFO) << "sighandler sig:" << signum;
|
|
- CO_GO std::bind(&HttpBenchMarkServer::Stop, &app);
|
|
|
|
|
|
+ CO_GO std::bind(&HttpBenchServer::Stop, &app);
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
int main(int argc, char* argv[]) {
|
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
|
gflags::SetUsageMessage("usage: exec --http=ip:port ");
|
|
gflags::SetUsageMessage("usage: exec --http=ip:port ");
|
|
|
|
|
|
- //google::InitGoogleLogging(argv[0]);
|
|
|
|
- //google::SetVLOGLevel(NULL, 26);
|
|
|
|
|
|
+ // google::InitGoogleLogging(argv[0]);
|
|
|
|
+ // google::SetVLOGLevel(NULL, 26);
|
|
|
|
|
|
signal(SIGINT, signalHandler);
|
|
signal(SIGINT, signalHandler);
|
|
signal(SIGTERM, signalHandler);
|
|
signal(SIGTERM, signalHandler);
|
|
|
|
|
|
app.Run();
|
|
app.Run();
|
|
}
|
|
}
|
|
-
|
|
|