ClickHouse/src/Server/TCPHandlerFactory.h
Kevin Michel ffc1fca296
Start/stop servers when listen_host/*_port changes
This allows starting and stopping separately each protocol server
without restarting ClickHouse.

This also allows adding or removing `listen_host` entries, which
start and stops servers for all enabled ports.

When stopping a server, the listening socket is immediately closed
(and available for another server).

Protocols with persistent connections try to wait for any currently
running query to finish before closing the connection, but idle
connection are closed quickly (depending on how often the protocol
is polled).

An extra ProfileEvent is added, `MainConfigLoads`, it is
incremented every time the configuration is reloaded. This helps
when trying to assess whether the new configuration was applied.
2021-12-24 08:26:02 +01:00

58 lines
1.8 KiB
C++

#pragma once
#include <Poco/Net/NetException.h>
#include <base/logger_useful.h>
#include <Server/IServer.h>
#include <Server/TCPHandler.h>
#include <Server/TCPServerConnectionFactory.h>
namespace Poco { class Logger; }
namespace DB
{
class TCPHandlerFactory : public TCPServerConnectionFactory
{
private:
IServer & server;
bool parse_proxy_protocol = false;
Poco::Logger * log;
std::string server_display_name;
class DummyTCPHandler : public Poco::Net::TCPServerConnection
{
public:
using Poco::Net::TCPServerConnection::TCPServerConnection;
void run() override {}
};
public:
/** parse_proxy_protocol_ - if true, expect and parse the header of PROXY protocol in every connection
* and set the information about forwarded address accordingly.
* See https://github.com/wolfeidau/proxyv2/blob/master/docs/proxy-protocol.txt
*/
TCPHandlerFactory(IServer & server_, bool secure_, bool parse_proxy_protocol_)
: server(server_), parse_proxy_protocol(parse_proxy_protocol_)
, log(&Poco::Logger::get(std::string("TCP") + (secure_ ? "S" : "") + "HandlerFactory"))
{
server_display_name = server.config().getString("display_name", getFQDNOrHostName());
}
Poco::Net::TCPServerConnection * createConnection(const Poco::Net::StreamSocket & socket, TCPServer & tcp_server) override
{
try
{
LOG_TRACE(log, "TCP Request. Address: {}", socket.peerAddress().toString());
return new TCPHandler(server, tcp_server, socket, parse_proxy_protocol, server_display_name);
}
catch (const Poco::Net::NetException &)
{
LOG_TRACE(log, "TCP Request. Client is not connected (most likely RST packet was sent).");
return new DummyTCPHandler(socket);
}
}
};
}