Bläddra i källkod

[ltio] a c++ implemented net-io based on coroutine and refactor (#6671)

* [ltio] a coroutine based c++ netlib

* update readme

* add benchmark source code

* json api encode response every time

Co-authored-by: gonghuan <[email protected]>
SuperHgO 4 år sedan
förälder
incheckning
2afc55d430

+ 23 - 0
frameworks/C++/ltio/CMakeLists.txt

@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(LightingIO VERSION 0.2.1 LANGUAGES C CXX)
+
+# for generate ycm complete database
+SET(CMAKE_CXX_STANDARD 14)
+
+ADD_DEFINITIONS(
+  -DUSE_TCMALLOC
+  -DUSENONSTD_STRING_VIEW
+  -DNET_ENABLE_REUSER_PORT
+)
+set(LTIO_BUILD_EXAMPLES OFF)
+set(LTIO_BUILD_UNITTESTS OFF)
+
+ADD_SUBDIRECTORY(ltio)
+
+ADD_EXECUTABLE(benchmark_server
+  http_benchmark.cc
+)
+TARGET_LINK_LIBRARIES(benchmark_server
+  ltio
+)

+ 23 - 0
frameworks/C++/ltio/README.md

@@ -0,0 +1,23 @@
+# ltio Benchmarking Test
+
+ltio is a coroutine based io implementations netlib
+
+### Test Type Implementation Source Code
+
+* [JSON](/json)
+* [PLAINTEXT](/plaintext)
+* [DB](None)
+* [QUERY](None)
+* [CACHED QUERY](None)
+* [UPDATE](None)
+
+
+## Test URLs
+### JSON
+
+http://localhost:5006/json
+
+### PLAINTEXT
+
+http://localhost:5006/plaintext
+

+ 26 - 0
frameworks/C++/ltio/benchmark_config.json

@@ -0,0 +1,26 @@
+{
+  "framework": "ltio",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 5006,
+        "approach": "Realistic",
+        "classification": "Platform",
+        "database": "None",
+        "framework": "None",
+        "language": "c++",
+        "flavor": "None",
+        "orm": "None",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "ltio",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 102 - 0
frameworks/C++/ltio/http_benchmark.cc

@@ -0,0 +1,102 @@
+#include <vector>
+#include <csignal>
+
+#include "base/utils/string/str_utils.h"
+#include "fmt/chrono.h"
+#include "gflags/gflags.h"
+#include "nlohmann/json.hpp"
+#include "net_io/server/http_server/http_server.h"
+
+
+using namespace lt::net;
+using namespace lt;
+using namespace base;
+
+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");
+
+class HttpBenchMarkServer {
+public:
+  ~HttpBenchMarkServer() {
+    LOG(INFO) << __func__ << " close app";
+    for (auto loop : loops) {
+      delete loop;
+    }
+    loops.clear();
+  }
+
+  void Run() {
+    main_loop.Start();
+
+
+    int loop_count = std::max(FLAGS_loops, int(std::thread::hardware_concurrency()));
+    LOG(INFO) << __func__ << " use loop count:" << loop_count;
+
+    for (int i = 0; i < loop_count; i++) {
+      auto loop = new(base::MessageLoop);
+      loop->Start();
+      loops.push_back(loop);
+    }
+
+    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());
+
+        response->InsertHeader("Server", "ltio");
+        auto tm = fmt::gmtime(std::time(nullptr));
+        response->InsertHeader("Date", fmt::format("{:%a, %d %b %Y %H:%M:%S %Z}", tm));
+        if (req->RequestUrl() == "/plaintext") {
+          response->MutableBody() = "Hello, World!";
+        } 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");
+        }
+        return context->Response(response);
+      });
+
+    main_loop.WaitLoopEnd();
+  }
+
+  void Stop() {
+    CHECK(CO_CANYIELD);
+    LOG(INFO) << __FUNCTION__ << " stop enter";
+    http_server.StopServer(CO_RESUMER);
+    CO_YIELD;
+    LOG(INFO) << __FUNCTION__ << " stop leave";
+    main_loop.QuitLoop();
+  }
+
+  HttpServer http_server;
+  //HttpCoroServer http_server;
+  base::MessageLoop main_loop;
+  std::vector<base::MessageLoop*> loops;
+};
+
+HttpBenchMarkServer app;
+
+void signalHandler( int signum ){
+  LOG(INFO) << "sighandler sig:" << signum;
+  CO_GO std::bind(&HttpBenchMarkServer::Stop, &app);
+}
+
+int main(int argc, char* argv[]) {
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+  gflags::SetUsageMessage("usage: exec --http=ip:port ");
+
+  //google::InitGoogleLogging(argv[0]);
+  //google::SetVLOGLevel(NULL, 26);
+
+  signal(SIGINT, signalHandler);
+  signal(SIGTERM, signalHandler);
+
+  app.Run();
+}
+

+ 17 - 0
frameworks/C++/ltio/ltio.dockerfile

@@ -0,0 +1,17 @@
+FROM buildpack-deps:focal
+
+RUN apt-get update -yqq && apt-get install -yqq software-properties-common unzip cmake
+RUN apt-get install -yqq build-essential libgoogle-perftools-dev git-core
+
+EXPOSE 5006
+RUN mkdir build_ltio
+
+ADD CMakeLists.txt build_ltio/
+ADD http_benchmark.cc build_ltio/
+
+WORKDIR /build_ltio
+RUN pwd; git clone https://github.com/echoface/ltio.git --recurse
+
+RUN ls; cmake .; make
+
+CMD ./benchmark_server $(nproc)