diff options
| author | Dan Engelbrecht <[email protected]> | 2023-09-14 03:54:57 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-14 09:54:57 +0200 |
| commit | e0da430c424192c24f5089ceb97f37062349e9ef (patch) | |
| tree | 2d83811f16839c1133a38b8a05c5ef1074a3701f /src | |
| parent | disable access logging on shared instances (#403) (diff) | |
| download | zen-e0da430c424192c24f5089ceb97f37062349e9ef.tar.xz zen-e0da430c424192c24f5089ceb97f37062349e9ef.zip | |
http and httpsys config options (#401)
* Added `--http-threads`, `--httpsys-async-work-threads`, `--httpsys-enable-request-logging` and `--httpsys-enable-async-response` command line options to zenserver
* remove unused CreateHttpSysServer
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenhttp/httpasio.cpp | 6 | ||||
| -rw-r--r-- | src/zenhttp/httpasio.h | 7 | ||||
| -rw-r--r-- | src/zenhttp/httpserver.cpp | 18 | ||||
| -rw-r--r-- | src/zenhttp/httpsys.cpp | 16 | ||||
| -rw-r--r-- | src/zenhttp/httpsys.h | 9 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/httpserver.h | 15 | ||||
| -rw-r--r-- | src/zenserver/config.cpp | 43 | ||||
| -rw-r--r-- | src/zenserver/config.h | 3 | ||||
| -rw-r--r-- | src/zenserver/zenserver.cpp | 4 |
9 files changed, 90 insertions, 31 deletions
diff --git a/src/zenhttp/httpasio.cpp b/src/zenhttp/httpasio.cpp index e12125bcc..4d1f35c2b 100644 --- a/src/zenhttp/httpasio.cpp +++ b/src/zenhttp/httpasio.cpp @@ -1339,7 +1339,9 @@ HttpAsioServerImpl::RouteRequest(std::string_view Url) ////////////////////////////////////////////////////////////////////////// namespace zen { -HttpAsioServer::HttpAsioServer() : m_Impl(std::make_unique<asio_http::HttpAsioServerImpl>()) +HttpAsioServer::HttpAsioServer(unsigned int ThreadCount) +: m_ThreadCount(ThreadCount != 0 ? ThreadCount : Max(std::thread::hardware_concurrency(), 8u)) +, m_Impl(std::make_unique<asio_http::HttpAsioServerImpl>()) { ZEN_DEBUG("Request object size: {} ({:#x})", sizeof(asio_http::HttpRequest), sizeof(asio_http::HttpRequest)); } @@ -1375,7 +1377,7 @@ HttpAsioServer::RegisterService(HttpService& Service) int HttpAsioServer::Initialize(int BasePort) { - m_BasePort = m_Impl->Start(gsl::narrow<uint16_t>(BasePort), Max(std::thread::hardware_concurrency(), 8u)); + m_BasePort = m_Impl->Start(gsl::narrow<uint16_t>(BasePort), m_ThreadCount); return m_BasePort; } diff --git a/src/zenhttp/httpasio.h b/src/zenhttp/httpasio.h index de25c538f..81aadfc23 100644 --- a/src/zenhttp/httpasio.h +++ b/src/zenhttp/httpasio.h @@ -18,7 +18,7 @@ namespace asio_http { class HttpAsioServer : public HttpServer { public: - HttpAsioServer(); + HttpAsioServer(unsigned int ThreadCount); ~HttpAsioServer(); virtual void RegisterService(HttpService& Service) override; @@ -28,8 +28,9 @@ public: virtual void Close() override; private: - Event m_ShutdownEvent; - int m_BasePort = 0; + Event m_ShutdownEvent; + int m_BasePort = 0; + unsigned int m_ThreadCount = 0; std::unique_ptr<asio_http::HttpAsioServerImpl> m_Impl; }; diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp index 5312e80a2..a98a3c9bb 100644 --- a/src/zenhttp/httpserver.cpp +++ b/src/zenhttp/httpserver.cpp @@ -714,11 +714,8 @@ enum class HttpServerClass kHttpNull }; -// Implemented in httpsys.cpp -Ref<HttpServer> CreateHttpSysServer(int Concurrency, int BackgroundWorkerThreads); - Ref<HttpServer> -CreateHttpServer(std::string_view ServerClass) +CreateHttpServer(const HttpServerConfig& Config) { using namespace std::literals; @@ -730,15 +727,15 @@ CreateHttpServer(std::string_view ServerClass) Class = HttpServerClass::kHttpAsio; #endif - if (ServerClass == "asio"sv) + if (Config.ServerClass == "asio"sv) { Class = HttpServerClass::kHttpAsio; } - else if (ServerClass == "httpsys"sv) + else if (Config.ServerClass == "httpsys"sv) { Class = HttpServerClass::kHttpSys; } - else if (ServerClass == "null"sv) + else if (Config.ServerClass == "null"sv) { Class = HttpServerClass::kHttpNull; } @@ -748,12 +745,15 @@ CreateHttpServer(std::string_view ServerClass) default: case HttpServerClass::kHttpAsio: ZEN_INFO("using asio HTTP server implementation"); - return Ref<HttpServer>(new HttpAsioServer()); + return Ref<HttpServer>(new HttpAsioServer(Config.ThreadCount)); #if ZEN_WITH_HTTPSYS case HttpServerClass::kHttpSys: ZEN_INFO("using http.sys server implementation"); - return Ref<HttpServer>(new HttpSysServer(std::thread::hardware_concurrency(), /* background worker threads */ 16)); + return Ref<HttpServer>(new HttpSysServer({.ThreadCount = Config.ThreadCount, + .AsyncWorkThreadCount = Config.HttpSys.AsyncWorkThreadCount, + .IsAsyncResponseEnabled = Config.HttpSys.IsAsyncResponseEnabled, + .IsRequestLoggingEnabled = Config.HttpSys.IsRequestLoggingEnabled})); #endif case HttpServerClass::kHttpNull: diff --git a/src/zenhttp/httpsys.cpp b/src/zenhttp/httpsys.cpp index 0b06f0558..2f8e0a898 100644 --- a/src/zenhttp/httpsys.cpp +++ b/src/zenhttp/httpsys.cpp @@ -721,11 +721,13 @@ HttpAsyncWorkRequest::AsyncWorkItem::Execute() \/ \/ \/ */ -HttpSysServer::HttpSysServer(unsigned int ThreadCount, unsigned int AsyncWorkThreadCount) +HttpSysServer::HttpSysServer(const Config& Config) : m_Log(logging::Get("http")) , m_RequestLog(logging::Get("http_requests")) -, m_ThreadPool(ThreadCount) -, m_AsyncWorkPool(AsyncWorkThreadCount, "http_async") +, m_IsRequestLoggingEnabled(Config.IsRequestLoggingEnabled) +, m_IsAsyncResponseEnabled(Config.IsAsyncResponseEnabled) +, m_ThreadPool(Config.ThreadCount != 0 ? Config.ThreadCount : std::thread::hardware_concurrency()) +, m_AsyncWorkPool(Config.AsyncWorkThreadCount != 0 ? Config.AsyncWorkThreadCount : 16, "http_async") { ULONG Result = HttpInitialize(HTTPAPI_VERSION_2, HTTP_INITIALIZE_SERVER, nullptr); @@ -737,7 +739,7 @@ HttpSysServer::HttpSysServer(unsigned int ThreadCount, unsigned int AsyncWorkThr m_IsHttpInitialized = true; m_IsOk = true; - ZEN_INFO("http.sys server started, using {} I/O threads and {} async worker threads", ThreadCount, AsyncWorkThreadCount); + ZEN_INFO("http.sys server started, using {} I/O threads and {} async worker threads", Config.ThreadCount, Config.AsyncWorkThreadCount); } HttpSysServer::~HttpSysServer() @@ -1697,11 +1699,5 @@ HttpSysServer::RegisterService(HttpService& Service) RegisterService(Service.BaseUri(), Service); } -Ref<HttpServer> -CreateHttpSysServer(int Concurrency, int BackgroundWorkerThreads) -{ - return Ref<HttpServer>(new HttpSysServer(Concurrency, BackgroundWorkerThreads)); -} - } // namespace zen #endif diff --git a/src/zenhttp/httpsys.h b/src/zenhttp/httpsys.h index cf16042d7..3a2a6065d 100644 --- a/src/zenhttp/httpsys.h +++ b/src/zenhttp/httpsys.h @@ -36,7 +36,14 @@ class HttpSysServer : public HttpServer friend class HttpSysTransaction; public: - explicit HttpSysServer(unsigned int ThreadCount, unsigned int AsyncWorkThreadCount); + struct Config + { + unsigned int ThreadCount = 0; + unsigned int AsyncWorkThreadCount = 0; + bool IsAsyncResponseEnabled = true; + bool IsRequestLoggingEnabled = false; + }; + explicit HttpSysServer(const Config& Config); ~HttpSysServer(); // HttpServer interface implementation diff --git a/src/zenhttp/include/zenhttp/httpserver.h b/src/zenhttp/include/zenhttp/httpserver.h index d1a562ee4..c233075be 100644 --- a/src/zenhttp/include/zenhttp/httpserver.h +++ b/src/zenhttp/include/zenhttp/httpserver.h @@ -182,7 +182,20 @@ public: virtual void Close() = 0; }; -Ref<HttpServer> CreateHttpServer(std::string_view ServerClass); +struct HttpServerConfig +{ + std::string ServerClass; // Choice of HTTP server implementation + unsigned int ThreadCount = 0; + + struct + { + unsigned int AsyncWorkThreadCount = 0; + bool IsAsyncResponseEnabled = true; + bool IsRequestLoggingEnabled = false; + } HttpSys; +}; + +Ref<HttpServer> CreateHttpServer(const HttpServerConfig& Config); ////////////////////////////////////////////////////////////////////////// diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp index 7ec3a0cee..64acdfe73 100644 --- a/src/zenserver/config.cpp +++ b/src/zenserver/config.cpp @@ -793,11 +793,22 @@ ParseConfigFile(const std::filesystem::path& Path, LuaOptions.AddOption("server.objectstore.buckets"sv, ServerOptions.ObjectStoreConfig); ////// network - LuaOptions.AddOption("network.httpserverclass"sv, ServerOptions.HttpServerClass, "http"sv); + LuaOptions.AddOption("network.httpserverclass"sv, ServerOptions.HttpServerConfig.ServerClass, "http"sv); + LuaOptions.AddOption("network.httpserverthreads"sv, ServerOptions.HttpServerConfig.ThreadCount, "http-threads"sv); LuaOptions.AddOption("network.port"sv, ServerOptions.BasePort, "port"sv); LuaOptions.AddOption("network.websocket.port"sv, ServerOptions.WebSocketPort, "websocket-port"sv); LuaOptions.AddOption("network.websocket.threadcount"sv, ServerOptions.WebSocketThreads, "websocket-threads"sv); + LuaOptions.AddOption("network.httpsys.async.workthreads"sv, + ServerOptions.HttpServerConfig.HttpSys.AsyncWorkThreadCount, + "httpsys-async-work-threads"sv); + LuaOptions.AddOption("network.httpsys.async.response"sv, + ServerOptions.HttpServerConfig.HttpSys.IsAsyncResponseEnabled, + "httpsys-enable-async-response"sv); + LuaOptions.AddOption("network.httpsys.requestlogging"sv, + ServerOptions.HttpServerConfig.HttpSys.IsRequestLoggingEnabled, + "httpsys-enable-request-logging"sv); + ////// trace LuaOptions.AddOption("trace.host"sv, ServerOptions.TraceHost, "tracehost"sv); LuaOptions.AddOption("trace.file"sv, ServerOptions.TraceFile, "tracefile"sv); @@ -1037,10 +1048,17 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) "", "http", "Select HTTP server implementation (asio|httpsys|null)", - cxxopts::value<std::string>(ServerOptions.HttpServerClass)->default_value(DefaultHttp), + cxxopts::value<std::string>(ServerOptions.HttpServerConfig.ServerClass)->default_value(DefaultHttp), "<http class>"); options.add_option("network", + "", + "http-threads", + "Number of http server connection threads", + cxxopts::value<unsigned int>(ServerOptions.HttpServerConfig.ThreadCount), + "<http threads>"); + + options.add_option("network", "p", "port", "Select HTTP port", @@ -1061,6 +1079,27 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) cxxopts::value<int>(ServerOptions.WebSocketThreads)->default_value("0"), ""); + options.add_option("httpsys", + "", + "httpsys-async-work-threads", + "Number of HttpSys async worker threads", + cxxopts::value<unsigned int>(ServerOptions.HttpServerConfig.HttpSys.AsyncWorkThreadCount), + "<httpsys workthreads>"); + + options.add_option("httpsys", + "", + "httpsys-enable-async-response", + "Enables Httpsys async response", + cxxopts::value<bool>(ServerOptions.HttpServerConfig.HttpSys.IsAsyncResponseEnabled)->default_value("true"), + "<httpsys async response>"); + + options.add_option("httpsys", + "", + "httpsys-enable-request-logging", + "Enables Httpsys request logging", + cxxopts::value<bool>(ServerOptions.HttpServerConfig.HttpSys.IsRequestLoggingEnabled), + "<httpsys request logging>"); + #if ZEN_WITH_TRACE options.add_option("ue-trace", "", diff --git a/src/zenserver/config.h b/src/zenserver/config.h index 0bb20aba4..f5438489d 100644 --- a/src/zenserver/config.h +++ b/src/zenserver/config.h @@ -3,6 +3,7 @@ #pragma once #include <zencore/zencore.h> +#include <zenhttp/httpserver.h> #include <filesystem> #include <string> #include <vector> @@ -120,13 +121,13 @@ struct ZenServerOptions ZenGcConfig GcConfig; ZenAuthConfig AuthConfig; ZenObjectStoreConfig ObjectStoreConfig; + zen::HttpServerConfig HttpServerConfig; std::filesystem::path DataDir; // Root directory for state (used for testing) std::filesystem::path ContentDir; // Root directory for serving frontend content (experimental) std::filesystem::path AbsLogFile; // Absolute path to main log file std::filesystem::path ConfigFile; // Path to Lua config file std::string ChildId; // Id assigned by parent process (used for lifetime management) std::string LogId; // Id for tagging log output - std::string HttpServerClass; // Choice of HTTP server implementation std::string EncryptionKey; // 256 bit AES encryption key std::string EncryptionIV; // 128 bit AES initialization vector int BasePort = 1337; // Service listen port (used for both UDP and TCP) diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 8056b6506..1baedd6eb 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -276,12 +276,12 @@ public: m_HealthService.SetHealthInfo({.DataRoot = m_DataRoot, .AbsLogPath = ServerOptions.AbsLogFile, - .HttpServerClass = std::string(ServerOptions.HttpServerClass), + .HttpServerClass = std::string(ServerOptions.HttpServerConfig.ServerClass), .BuildVersion = std::string(ZEN_CFG_VERSION_BUILD_STRING_FULL)}); // Ok so now we're configured, let's kick things off - m_Http = zen::CreateHttpServer(ServerOptions.HttpServerClass); + m_Http = zen::CreateHttpServer(ServerOptions.HttpServerConfig); int EffectiveBasePort = m_Http->Initialize(ServerOptions.BasePort); if (ServerOptions.WebSocketPort != 0) |