add a ServerFactory class
This refactors the Server creation code, to make it easier to create new Server implementations in the future, and to separate the LibEventServer code from the main hphp_runtime library. This defines a new ServerFactory interface, and a ServerFactoryRegistry which maintains a mapping of server type strings to ServerFactory objects. The HttpServer code now uses a ServerFactory to create the m_pageServer, rather than directly creating a LibEventServer object.
Esse commit está contido em:
@@ -94,6 +94,7 @@ std::string RuntimeOption::AdminLogSymLink;
|
||||
std::string RuntimeOption::Tier;
|
||||
std::string RuntimeOption::Host;
|
||||
std::string RuntimeOption::DefaultServerNameSuffix;
|
||||
std::string RuntimeOption::ServerType = "libevent";
|
||||
std::string RuntimeOption::ServerIP;
|
||||
std::string RuntimeOption::ServerPrimaryIP;
|
||||
int RuntimeOption::ServerPort;
|
||||
@@ -670,6 +671,7 @@ void RuntimeOption::Load(Hdf &config, StringVec *overwrites /* = NULL */,
|
||||
Hdf server = config["Server"];
|
||||
Host = server["Host"].getString();
|
||||
DefaultServerNameSuffix = server["DefaultServerNameSuffix"].getString();
|
||||
ServerType = server["Type"].getString(ServerType);
|
||||
ServerIP = server["IP"].getString();
|
||||
ServerPrimaryIP = Util::GetPrimaryIP();
|
||||
ServerPort = server["Port"].getUInt16(80);
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
static std::string Tier;
|
||||
static std::string Host;
|
||||
static std::string DefaultServerNameSuffix;
|
||||
static std::string ServerType;
|
||||
static std::string ServerIP;
|
||||
static std::string ServerPrimaryIP;
|
||||
static int ServerPort;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#ifndef incl_HPHP_ADMIN_REQUEST_HANDLER_H_
|
||||
#define incl_HPHP_ADMIN_REQUEST_HANDLER_H_
|
||||
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
#include "hphp/runtime/base/server/access_log.h"
|
||||
#include "hphp/runtime/base/server/server.h"
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
#ifndef incl_HPHP_HTTP_REQUEST_HANDLER_H_
|
||||
#define incl_HPHP_HTTP_REQUEST_HANDLER_H_
|
||||
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
#include "hphp/runtime/base/util/string_buffer.h"
|
||||
#include "hphp/runtime/base/server/virtual_host.h"
|
||||
#include "hphp/runtime/base/server/access_log.h"
|
||||
#include "hphp/runtime/base/server/server.h"
|
||||
|
||||
namespace HPHP {
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "hphp/runtime/base/server/http_server.h"
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
#include "hphp/runtime/base/server/libevent_server_with_fd.h"
|
||||
#include "hphp/runtime/base/server/libevent_server_with_takeover.h"
|
||||
#include "hphp/runtime/base/server/http_request_handler.h"
|
||||
#include "hphp/runtime/base/server/admin_request_handler.h"
|
||||
#include "hphp/runtime/base/server/server_stats.h"
|
||||
@@ -34,6 +31,7 @@
|
||||
#include "hphp/runtime/base/program_functions.h"
|
||||
#include "hphp/runtime/debugger/debugger.h"
|
||||
#include "hphp/util/db_conn.h"
|
||||
#include "hphp/util/process.h"
|
||||
#include "hphp/util/ssl_init.h"
|
||||
#include "hphp/runtime/ext/ext_apc.h"
|
||||
|
||||
@@ -68,28 +66,16 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
|
||||
additionalThreads = RuntimeOption::ServerThreadCount - startingThreadCount;
|
||||
}
|
||||
|
||||
if (RuntimeOption::ServerPortFd != -1 || RuntimeOption::SSLPortFd != -1) {
|
||||
auto const server = boost::make_shared<LibEventServerWithFd>(
|
||||
RuntimeOption::ServerIP, RuntimeOption::ServerPort,
|
||||
startingThreadCount,
|
||||
RuntimeOption::RequestTimeoutSeconds);
|
||||
server->setServerSocketFd(RuntimeOption::ServerPortFd);
|
||||
server->setSSLSocketFd(RuntimeOption::SSLPortFd);
|
||||
m_pageServer = server;
|
||||
} else if (RuntimeOption::TakeoverFilename.empty()) {
|
||||
auto const server = boost::make_shared<LibEventServer>(
|
||||
RuntimeOption::ServerIP, RuntimeOption::ServerPort,
|
||||
startingThreadCount,
|
||||
RuntimeOption::RequestTimeoutSeconds);
|
||||
m_pageServer = server;
|
||||
} else {
|
||||
auto const server = boost::make_shared<LibEventServerWithTakeover>(
|
||||
RuntimeOption::ServerIP, RuntimeOption::ServerPort,
|
||||
startingThreadCount,
|
||||
RuntimeOption::RequestTimeoutSeconds);
|
||||
server->setTransferFilename(RuntimeOption::TakeoverFilename);
|
||||
m_pageServer = server;
|
||||
}
|
||||
auto serverFactory = ServerFactoryRegistry::getInstance()->getFactory
|
||||
(RuntimeOption::ServerType);
|
||||
ServerOptions options
|
||||
(RuntimeOption::ServerIP, RuntimeOption::ServerPort,
|
||||
startingThreadCount,
|
||||
std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds));
|
||||
options.m_serverFD = RuntimeOption::ServerPortFd;
|
||||
options.m_sslFD = RuntimeOption::SSLPortFd;
|
||||
options.m_takeoverFilename = RuntimeOption::TakeoverFilename;
|
||||
m_pageServer = serverFactory->createServer(options);
|
||||
m_pageServer->addTakeoverListener(this);
|
||||
|
||||
if (additionalThreads) {
|
||||
@@ -108,10 +94,11 @@ HttpServer::HttpServer(void *sslCTX /* = NULL */)
|
||||
m_pageServer->enableSSL(m_sslCTX, RuntimeOption::SSLPort);
|
||||
}
|
||||
|
||||
m_adminServer = boost::make_shared<LibEventServer>(
|
||||
RuntimeOption::ServerIP, RuntimeOption::AdminServerPort,
|
||||
RuntimeOption::AdminThreadCount,
|
||||
RuntimeOption::RequestTimeoutSeconds);
|
||||
m_adminServer = ServerFactoryRegistry::createServer
|
||||
(RuntimeOption::ServerType,
|
||||
RuntimeOption::ServerIP, RuntimeOption::AdminServerPort,
|
||||
RuntimeOption::AdminThreadCount,
|
||||
std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds));
|
||||
m_adminServer->setRequestHandlerFactory<AdminRequestHandler>();
|
||||
|
||||
for (unsigned int i = 0; i < RuntimeOption::SatelliteServerInfos.size();
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "hphp/runtime/base/server/server.h"
|
||||
#include "hphp/runtime/base/server/satellite_server.h"
|
||||
#include "hphp/runtime/base/server/libevent_server_with_takeover.h"
|
||||
#include "hphp/util/async_func.h"
|
||||
#include "hphp/runtime/base/server/service_thread.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
#include "hphp/runtime/base/server/libevent_server_with_fd.h"
|
||||
#include "hphp/runtime/base/server/libevent_server_with_takeover.h"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LibEventServerFactory : public ServerFactory {
|
||||
public:
|
||||
LibEventServerFactory() {}
|
||||
|
||||
virtual ServerPtr createServer(const ServerOptions& options);
|
||||
};
|
||||
|
||||
ServerPtr LibEventServerFactory::createServer(const ServerOptions& options) {
|
||||
if (options.m_serverFD != -1 || options.m_sslFD != -1) {
|
||||
auto const server = boost::make_shared<LibEventServerWithFd>
|
||||
(options.m_address, options.m_port, options.m_numThreads,
|
||||
options.m_timeout.count());
|
||||
server->setServerSocketFd(options.m_serverFD);
|
||||
server->setSSLSocketFd(options.m_sslFD);
|
||||
return server;
|
||||
}
|
||||
|
||||
if (!options.m_takeoverFilename.empty()) {
|
||||
auto const server = boost::make_shared<LibEventServerWithTakeover>
|
||||
(options.m_address, options.m_port, options.m_numThreads,
|
||||
options.m_timeout.count());
|
||||
server->setTransferFilename(options.m_takeoverFilename);
|
||||
return server;
|
||||
}
|
||||
|
||||
return boost::make_shared<LibEventServer>(options.m_address, options.m_port,
|
||||
options.m_numThreads,
|
||||
options.m_timeout.count());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* Automatically register LibEventServerFactory on program start
|
||||
*/
|
||||
void register_libevent_server() __attribute__((constructor));
|
||||
void register_libevent_server() {
|
||||
auto registry = HPHP::ServerFactoryRegistry::getInstance();
|
||||
auto factory = boost::make_shared<HPHP::LibEventServerFactory>();
|
||||
registry->registerFactory("libevent", factory);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#include "hphp/runtime/base/server/satellite_server.h"
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
#include "hphp/runtime/base/server/http_request_handler.h"
|
||||
#include "hphp/runtime/base/server/rpc_request_handler.h"
|
||||
#include "hphp/runtime/base/server/virtual_host.h"
|
||||
@@ -41,8 +40,8 @@ SatelliteServerInfo::SatelliteServerInfo(Hdf hdf) {
|
||||
m_threadCount = hdf["ThreadCount"].getInt32(5);
|
||||
m_maxRequest = hdf["MaxRequest"].getInt32(500);
|
||||
m_maxDuration = hdf["MaxDuration"].getInt32(120);
|
||||
m_timeoutSeconds =
|
||||
hdf["TimeoutSeconds"].getInt32(RuntimeOption::RequestTimeoutSeconds);
|
||||
m_timeoutSeconds = std::chrono::seconds
|
||||
(hdf["TimeoutSeconds"].getInt32(RuntimeOption::RequestTimeoutSeconds));
|
||||
m_reqInitFunc = hdf["RequestInitFunction"].getString("");
|
||||
m_reqInitDoc = hdf["RequestInitDocument"].getString("");
|
||||
m_password = hdf["Password"].getString("");
|
||||
@@ -85,15 +84,15 @@ bool SatelliteServerInfo::checkMainURL(const std::string& path) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// InternalPageServer: LibEventServer + allowed URL checking
|
||||
// InternalPageServer: Server + allowed URL checking
|
||||
|
||||
class InternalPageServer : public SatelliteServer {
|
||||
public:
|
||||
explicit InternalPageServer(SatelliteServerInfoPtr info)
|
||||
: m_allowedURLs(info->getURLs()) {
|
||||
m_server = boost::make_shared<LibEventServer>(
|
||||
RuntimeOption::ServerIP, info->getPort(), info->getThreadCount(),
|
||||
info->getTimeoutSeconds());
|
||||
m_server = ServerFactoryRegistry::createServer
|
||||
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
|
||||
info->getThreadCount(), info->getTimeoutSeconds());
|
||||
m_server->setRequestHandlerFactory<HttpRequestHandler>();
|
||||
m_server->setUrlChecker(std::bind(&InternalPageServer::checkURL, this,
|
||||
std::placeholders::_1));
|
||||
@@ -125,14 +124,14 @@ private:
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DanglingPageServer: same as LibEventServer
|
||||
// DanglingPageServer: same as Server
|
||||
|
||||
class DanglingPageServer : public SatelliteServer {
|
||||
public:
|
||||
explicit DanglingPageServer(SatelliteServerInfoPtr info) {
|
||||
m_server = boost::make_shared<LibEventServer>(
|
||||
RuntimeOption::ServerIP, info->getPort(), info->getThreadCount(),
|
||||
info->getTimeoutSeconds());
|
||||
m_server = ServerFactoryRegistry::createServer
|
||||
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
|
||||
info->getThreadCount(), info->getTimeoutSeconds());
|
||||
m_server->setRequestHandlerFactory<HttpRequestHandler>();
|
||||
}
|
||||
|
||||
@@ -148,14 +147,14 @@ private:
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RPCServer: LibEventServer + RPCRequestHandler
|
||||
// RPCServer: Server + RPCRequestHandler
|
||||
|
||||
class RPCServer : public SatelliteServer {
|
||||
public:
|
||||
explicit RPCServer(SatelliteServerInfoPtr info) {
|
||||
m_server = boost::make_shared<LibEventServer>(
|
||||
RuntimeOption::ServerIP, info->getPort(), info->getThreadCount(),
|
||||
info->getTimeoutSeconds());
|
||||
m_server = ServerFactoryRegistry::createServer
|
||||
(RuntimeOption::ServerType, RuntimeOption::ServerIP, info->getPort(),
|
||||
info->getThreadCount(), info->getTimeoutSeconds());
|
||||
m_server->setRequestHandlerFactory([info] {
|
||||
auto handler = make_unique<RPCRequestHandler>();
|
||||
handler->setServerInfo(info);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "hphp/util/hdf.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -76,7 +78,7 @@ public:
|
||||
int getThreadCount() const { return m_threadCount;}
|
||||
|
||||
// for all libevent servers
|
||||
int getTimeoutSeconds() const { return m_timeoutSeconds;}
|
||||
std::chrono::seconds getTimeoutSeconds() const { return m_timeoutSeconds;}
|
||||
|
||||
// only for InternalPageServer
|
||||
const std::set<std::string> &getURLs() const { return m_urls;}
|
||||
@@ -97,7 +99,7 @@ protected:
|
||||
int m_threadCount;
|
||||
int m_maxRequest;
|
||||
int m_maxDuration;
|
||||
int m_timeoutSeconds;
|
||||
std::chrono::seconds m_timeoutSeconds;
|
||||
std::set<std::string> m_urls; // url regex patterns
|
||||
std::string m_reqInitFunc;
|
||||
std::string m_reqInitDoc;
|
||||
|
||||
@@ -54,5 +54,53 @@ Server::Server(const std::string &address, int port, int threadCount)
|
||||
m_status(NOT_YET_STARTED) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ServerPtr ServerFactory::createServer(const std::string &address,
|
||||
uint16_t port,
|
||||
int numThreads,
|
||||
std::chrono::seconds timeout) {
|
||||
ServerOptions options(address, port, numThreads, timeout);
|
||||
return createServer(options);
|
||||
}
|
||||
|
||||
ServerFactoryRegistry::ServerFactoryRegistry()
|
||||
: m_lock(false) {
|
||||
}
|
||||
|
||||
ServerFactoryRegistry *ServerFactoryRegistry::getInstance() {
|
||||
static ServerFactoryRegistry singleton;
|
||||
return &singleton;
|
||||
}
|
||||
|
||||
ServerPtr ServerFactoryRegistry::createServer(const std::string &type,
|
||||
const std::string &address,
|
||||
uint16_t port,
|
||||
int numThreads,
|
||||
std::chrono::seconds timeout) {
|
||||
auto factory = getInstance()->getFactory(type);
|
||||
ServerOptions options(address, port, numThreads, timeout);
|
||||
return factory->createServer(options);
|
||||
}
|
||||
|
||||
void ServerFactoryRegistry::registerFactory(const std::string &name,
|
||||
const ServerFactoryPtr &factory) {
|
||||
Lock lock(m_lock);
|
||||
auto ret = m_factories.insert(std::make_pair(name, factory));
|
||||
if (!ret.second) {
|
||||
throw ServerException("a factory already exists for server type \"%s\"",
|
||||
name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ServerFactoryPtr ServerFactoryRegistry::getFactory(const std::string &name) {
|
||||
Lock lock(m_lock);
|
||||
auto it = m_factories.find(name);
|
||||
if (it == m_factories.end()) {
|
||||
throw ServerException("no factory for server type \"%s\"", name.c_str());
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "hphp/util/exception.h"
|
||||
#include "hphp/util/lock.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
@@ -67,6 +68,7 @@ namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DECLARE_BOOST_TYPES(Server);
|
||||
DECLARE_BOOST_TYPES(ServerFactory);
|
||||
|
||||
/**
|
||||
* Base class of an HTTP request handler. Defining minimal interface an
|
||||
@@ -250,6 +252,73 @@ private:
|
||||
RunStatus m_status;
|
||||
};
|
||||
|
||||
class ServerOptions {
|
||||
public:
|
||||
ServerOptions(const std::string &address,
|
||||
uint16_t port,
|
||||
int numThreads,
|
||||
std::chrono::seconds timeout)
|
||||
: m_address(address),
|
||||
m_port(port),
|
||||
m_numThreads(numThreads),
|
||||
m_timeout(timeout),
|
||||
m_serverFD(-1),
|
||||
m_sslFD(-1),
|
||||
m_takeoverFilename() {
|
||||
}
|
||||
|
||||
std::string m_address;
|
||||
uint16_t m_port;
|
||||
int m_numThreads;
|
||||
std::chrono::seconds m_timeout;
|
||||
int m_serverFD;
|
||||
int m_sslFD;
|
||||
std::string m_takeoverFilename;
|
||||
};
|
||||
|
||||
/**
|
||||
* A ServerFactory knows how to create Server objects.
|
||||
*/
|
||||
class ServerFactory : private boost::noncopyable {
|
||||
public:
|
||||
virtual ~ServerFactory() {}
|
||||
|
||||
virtual ServerPtr createServer(const ServerOptions &options) = 0;
|
||||
|
||||
ServerPtr createServer(const std::string &address,
|
||||
uint16_t port,
|
||||
int numThreads,
|
||||
std::chrono::seconds timeout);
|
||||
};
|
||||
|
||||
/**
|
||||
* A registry mapping server type names to ServerFactory objects.
|
||||
*
|
||||
* This allows new server types to be plugged in dynamically, without having to
|
||||
* hard code the list of all possible server types.
|
||||
*/
|
||||
class ServerFactoryRegistry : private boost::noncopyable {
|
||||
public:
|
||||
ServerFactoryRegistry();
|
||||
|
||||
static ServerFactoryRegistry *getInstance();
|
||||
|
||||
static ServerPtr createServer(const std::string &type,
|
||||
const std::string &address,
|
||||
uint16_t port,
|
||||
int numThreads,
|
||||
std::chrono::seconds timeout);
|
||||
|
||||
void registerFactory(const std::string &name,
|
||||
const ServerFactoryPtr &factory);
|
||||
|
||||
ServerFactoryPtr getFactory(const std::string &name);
|
||||
|
||||
private:
|
||||
Mutex m_lock;
|
||||
std::map<std::string, ServerFactoryPtr> m_factories;
|
||||
};
|
||||
|
||||
/**
|
||||
* All exceptions Server throws should derive from this base class.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "hphp/runtime/base/array/array_init.h"
|
||||
#include "hphp/util/json.h"
|
||||
#include "hphp/util/compatibility.h"
|
||||
#include "hphp/util/process.h"
|
||||
#include "hphp/runtime/base/hardware_counter.h"
|
||||
|
||||
using std::list;
|
||||
@@ -307,7 +308,7 @@ void ServerStats::FreeSlots(list<TimeSlot*> &slots) {
|
||||
|
||||
class Writer {
|
||||
public:
|
||||
Writer(ostream &out) : m_out(out), m_indent(0) {}
|
||||
explicit Writer(ostream &out) : m_out(out), m_indent(0) {}
|
||||
virtual ~Writer() {}
|
||||
|
||||
virtual void writeFileHeader() = 0;
|
||||
@@ -350,7 +351,7 @@ protected:
|
||||
|
||||
class XMLWriter : public Writer {
|
||||
public:
|
||||
XMLWriter(ostream &out) : Writer(out) {}
|
||||
explicit XMLWriter(ostream &out) : Writer(out) {}
|
||||
|
||||
|
||||
virtual void writeFileHeader() {
|
||||
@@ -484,7 +485,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
JSONWriter(ostream &out) : Writer(out),
|
||||
explicit JSONWriter(ostream &out) : Writer(out),
|
||||
m_justIndented(true) {
|
||||
|
||||
// A valid json object begins in the nameless context. See
|
||||
@@ -535,7 +536,7 @@ public:
|
||||
class HTMLWriter : public Writer {
|
||||
|
||||
public:
|
||||
HTMLWriter(ostream &out) : Writer(out) {}
|
||||
explicit HTMLWriter(ostream &out) : Writer(out) {}
|
||||
|
||||
virtual void writeFileHeader() {
|
||||
m_out << "<!doctype html>\n<html>\n<head>\n"
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "hphp/runtime/base/server/http_request_handler.h"
|
||||
#include "hphp/runtime/base/util/http_client.h"
|
||||
#include "hphp/runtime/base/runtime_option.h"
|
||||
#include "hphp/runtime/base/server/libevent_server.h"
|
||||
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário