aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-09-14 03:54:57 -0400
committerGitHub <[email protected]>2023-09-14 09:54:57 +0200
commite0da430c424192c24f5089ceb97f37062349e9ef (patch)
tree2d83811f16839c1133a38b8a05c5ef1074a3701f /src
parentdisable access logging on shared instances (#403) (diff)
downloadzen-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.cpp6
-rw-r--r--src/zenhttp/httpasio.h7
-rw-r--r--src/zenhttp/httpserver.cpp18
-rw-r--r--src/zenhttp/httpsys.cpp16
-rw-r--r--src/zenhttp/httpsys.h9
-rw-r--r--src/zenhttp/include/zenhttp/httpserver.h15
-rw-r--r--src/zenserver/config.cpp43
-rw-r--r--src/zenserver/config.h3
-rw-r--r--src/zenserver/zenserver.cpp4
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)