Add the getLoop() method to the HttpAppFramework class
This commit is contained in:
parent
798861a1cc
commit
65c101bee0
|
@ -71,8 +71,8 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
///Run the event loop
|
||||
/**
|
||||
* Calling this method starts the IO event loops and the main loop of the application;
|
||||
* Usually, the thread that calls this method is the main thread of the application;
|
||||
* This method blocks the calling thread until the main loop exits.
|
||||
* This method MUST be called in the main thread.
|
||||
* This method blocks the main thread until the main event loop exits.
|
||||
*/
|
||||
virtual void run() = 0;
|
||||
|
||||
|
@ -83,7 +83,7 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
/**
|
||||
* Calling this method results in stopping all network IO in the
|
||||
* framework and interrupting the blocking of the run() method. Usually,
|
||||
* after calling this method, the application will exit.
|
||||
* after calling this method, the application exits.
|
||||
*
|
||||
* NOTE:
|
||||
* This method can be called in any thread and anywhere.
|
||||
|
@ -91,16 +91,15 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
*/
|
||||
virtual void quit() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// ///Get the event loop of the framework;
|
||||
// /**
|
||||
// * NOTE:
|
||||
// * The event loop is not the network IO loop, but the main event loop
|
||||
// * of the framework in which only some timer tasks are running;
|
||||
// * You can run some timer tasks or other tasks in this loop;
|
||||
// */
|
||||
// // virtual trantor::EventLoop *loop() = 0;
|
||||
///////////////////////////////////////////////////////////
|
||||
///Get the main event loop of the framework;
|
||||
/**
|
||||
* NOTE:
|
||||
* The event loop is not the network IO loop, but the main event loop
|
||||
* of the framework in which only some timer tasks are running;
|
||||
* User can run some timer tasks or other tasks in this loop;
|
||||
* This method can be call in any thread.
|
||||
*/
|
||||
virtual trantor::EventLoop *getLoop() = 0;
|
||||
|
||||
///Load the configuration file with json format.
|
||||
virtual void loadConfigFile(const std::string &fileName) = 0;
|
||||
|
@ -130,18 +129,18 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
* @param filtersAndMethods is the same as the third parameter in the above method.
|
||||
*
|
||||
* FOR EXAMPLE:
|
||||
* app.registerHandler("/hello?username={1}",
|
||||
[](const HttpRequestPtr& req,
|
||||
const std::function<void (const HttpResponsePtr &)> & callback,
|
||||
const std::string &name)
|
||||
{
|
||||
Json::Value json;
|
||||
json["result"]="ok";
|
||||
json["message"]=std::string("hello,")+name;
|
||||
auto resp=HttpResponse::newHttpJsonResponse(json);
|
||||
callback(resp);
|
||||
},
|
||||
{Get,"LoginFilter"});
|
||||
* app.registerHandler("/hello?username={1}",
|
||||
* [](const HttpRequestPtr& req,
|
||||
* const std::function<void (const HttpResponsePtr &)> & callback,
|
||||
* const std::string &name)
|
||||
* {
|
||||
* Json::Value json;
|
||||
* json["result"]="ok";
|
||||
* json["message"]=std::string("hello,")+name;
|
||||
* auto resp=HttpResponse::newHttpJsonResponse(json);
|
||||
* callback(resp);
|
||||
* },
|
||||
* {Get,"LoginFilter"});
|
||||
*
|
||||
* NOTE:
|
||||
* As you can see in the above example, this method supports parameters mapping.
|
||||
|
@ -182,6 +181,7 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
}
|
||||
registerHttpController(pathPattern, binder, validMethods, filters);
|
||||
}
|
||||
|
||||
/// Register a WebSocketController into the framework.
|
||||
/// The parameters of this method are the same as those in the registerHttpSimpleController() method.
|
||||
virtual void registerWebSocketController(const std::string &pathName,
|
||||
|
@ -424,9 +424,17 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
|
||||
#if USE_ORM
|
||||
///Get a database client by @param name
|
||||
/**
|
||||
* NOTE:
|
||||
* This method must be called after the framework has been run.
|
||||
*/
|
||||
virtual orm::DbClientPtr getDbClient(const std::string &name = "default") = 0;
|
||||
|
||||
///Get a 'fast' database client by @param name
|
||||
/**
|
||||
* NOTE:
|
||||
* This method must be called after the framework has been run.
|
||||
*/
|
||||
virtual orm::DbClientPtr getFastDbClient(const std::string &name = "default") = 0;
|
||||
|
||||
///Create a database client
|
||||
|
|
|
@ -44,6 +44,13 @@
|
|||
using namespace drogon;
|
||||
using namespace std::placeholders;
|
||||
|
||||
///Make sure that the main event loop is initialized in the main thread.
|
||||
drogon::InitBeforeMainFunction drogon::HttpAppFrameworkImpl::_initFirst([]() {
|
||||
HttpAppFrameworkImpl::instance().getLoop()->runInLoop([]() {
|
||||
LOG_TRACE << "Initialize the main event loop in the main thread";
|
||||
});
|
||||
});
|
||||
|
||||
static void godaemon(void)
|
||||
{
|
||||
printf("Initializing daemon mode\n");
|
||||
|
@ -212,9 +219,9 @@ void HttpAppFrameworkImpl::run()
|
|||
//go daemon!
|
||||
godaemon();
|
||||
#ifdef __linux__
|
||||
loop()->resetTimerQueue();
|
||||
getLoop()->resetTimerQueue();
|
||||
#endif
|
||||
loop()->resetAfterFork();
|
||||
getLoop()->resetAfterFork();
|
||||
}
|
||||
//set relaunching
|
||||
if (_relaunchOnError)
|
||||
|
@ -237,7 +244,7 @@ void HttpAppFrameworkImpl::run()
|
|||
sleep(1);
|
||||
LOG_INFO << "start new process";
|
||||
}
|
||||
loop()->resetAfterFork();
|
||||
getLoop()->resetAfterFork();
|
||||
}
|
||||
|
||||
//set logger
|
||||
|
@ -271,7 +278,7 @@ void HttpAppFrameworkImpl::run()
|
|||
|
||||
if (!_libFilePaths.empty())
|
||||
{
|
||||
_sharedLibManagerPtr = std::unique_ptr<SharedLibManager>(new SharedLibManager(loop(), _libFilePaths));
|
||||
_sharedLibManagerPtr = std::unique_ptr<SharedLibManager>(new SharedLibManager(getLoop(), _libFilePaths));
|
||||
}
|
||||
std::vector<std::shared_ptr<HttpServer>> servers;
|
||||
std::vector<std::shared_ptr<EventLoopThread>> loopThreads;
|
||||
|
@ -399,21 +406,21 @@ void HttpAppFrameworkImpl::run()
|
|||
tmpTimeout = tmpTimeout / 100;
|
||||
}
|
||||
}
|
||||
_sessionMapPtr = std::unique_ptr<CacheMap<std::string, SessionPtr>>(new CacheMap<std::string, SessionPtr>(loop(), 1.0, wheelNum, bucketNum));
|
||||
_sessionMapPtr = std::unique_ptr<CacheMap<std::string, SessionPtr>>(new CacheMap<std::string, SessionPtr>(getLoop(), 1.0, wheelNum, bucketNum));
|
||||
}
|
||||
else if (_sessionTimeout == 0)
|
||||
{
|
||||
_sessionMapPtr = std::unique_ptr<CacheMap<std::string, SessionPtr>>(new CacheMap<std::string, SessionPtr>(loop(), 0, 0, 0));
|
||||
_sessionMapPtr = std::unique_ptr<CacheMap<std::string, SessionPtr>>(new CacheMap<std::string, SessionPtr>(getLoop(), 0, 0, 0));
|
||||
}
|
||||
}
|
||||
_responseCachingMap = std::unique_ptr<CacheMap<std::string, HttpResponsePtr>>(new CacheMap<std::string, HttpResponsePtr>(loop(), 1.0, 4, 50)); //Max timeout up to about 70 days;
|
||||
_responseCachingMap = std::unique_ptr<CacheMap<std::string, HttpResponsePtr>>(new CacheMap<std::string, HttpResponsePtr>(getLoop(), 1.0, 4, 50)); //Max timeout up to about 70 days;
|
||||
|
||||
// Let listener event loops run when everything is ready.
|
||||
for (auto &loopTh : loopThreads)
|
||||
{
|
||||
loopTh->run();
|
||||
}
|
||||
loop()->loop();
|
||||
getLoop()->loop();
|
||||
}
|
||||
#if USE_ORM
|
||||
void HttpAppFrameworkImpl::createDbClients(const std::vector<trantor::EventLoop *> &ioloops)
|
||||
|
@ -745,7 +752,7 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequestImplPtr &req, std::fu
|
|||
_httpSimpleCtrlsRouter.route(req, std::move(callback), needSetJsessionid, std::move(sessionId));
|
||||
}
|
||||
|
||||
trantor::EventLoop *HttpAppFrameworkImpl::loop()
|
||||
trantor::EventLoop *HttpAppFrameworkImpl::getLoop()
|
||||
{
|
||||
static trantor::EventLoop loop;
|
||||
return &loop;
|
||||
|
|
|
@ -37,6 +37,13 @@
|
|||
|
||||
namespace drogon
|
||||
{
|
||||
struct InitBeforeMainFunction
|
||||
{
|
||||
InitBeforeMainFunction(const std::function<void()> &func)
|
||||
{
|
||||
func();
|
||||
}
|
||||
};
|
||||
class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
{
|
||||
public:
|
||||
|
@ -112,12 +119,12 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
return _running;
|
||||
}
|
||||
|
||||
trantor::EventLoop *loop();
|
||||
virtual trantor::EventLoop *getLoop() override;
|
||||
|
||||
virtual void quit() override
|
||||
{
|
||||
if (loop()->isRunning())
|
||||
loop()->quit();
|
||||
if (getLoop()->isRunning())
|
||||
getLoop()->quit();
|
||||
}
|
||||
|
||||
virtual void setServerHeaderField(const std::string &server) override
|
||||
|
@ -126,7 +133,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
assert(server.find("\r\n") == std::string::npos);
|
||||
_serverHeader = "Server: " + server + "\r\n";
|
||||
}
|
||||
|
||||
|
||||
const std::string &getServerHeaderString() const
|
||||
{
|
||||
return _serverHeader;
|
||||
|
@ -237,6 +244,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
std::map<std::string, std::map<trantor::EventLoop *, orm::DbClientPtr>> _dbFastClientsMap;
|
||||
void createDbClients(const std::vector<trantor::EventLoop *> &ioloops);
|
||||
#endif
|
||||
static InitBeforeMainFunction _initFirst;
|
||||
};
|
||||
|
||||
} // namespace drogon
|
||||
|
|
|
@ -304,10 +304,10 @@ void HttpClientImpl::onRecvMessage(const trantor::TcpConnectionPtr &connPtr, tra
|
|||
HttpClientPtr HttpClient::newHttpClient(const std::string &ip, uint16_t port, bool useSSL, trantor::EventLoop *loop)
|
||||
{
|
||||
bool isIpv6 = ip.find(":") == std::string::npos ? false : true;
|
||||
return std::make_shared<HttpClientImpl>(loop == nullptr ? HttpAppFrameworkImpl::instance().loop() : loop, trantor::InetAddress(ip, port, isIpv6), useSSL);
|
||||
return std::make_shared<HttpClientImpl>(loop == nullptr ? HttpAppFrameworkImpl::instance().getLoop() : loop, trantor::InetAddress(ip, port, isIpv6), useSSL);
|
||||
}
|
||||
|
||||
HttpClientPtr HttpClient::newHttpClient(const std::string &hostString, trantor::EventLoop *loop)
|
||||
{
|
||||
return std::make_shared<HttpClientImpl>(loop == nullptr ? HttpAppFrameworkImpl::instance().loop() : loop, hostString);
|
||||
return std::make_shared<HttpClientImpl>(loop == nullptr ? HttpAppFrameworkImpl::instance().getLoop() : loop, hostString);
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ add_executable(view_data_test HttpViewDataTest.cc)
|
|||
add_executable(md5_test Md5Test.cc ../src/ssl_funcs/Md5.cc)
|
||||
add_executable(http_full_date_test HttpFullDateTest.cc)
|
||||
add_executable(gzip_test GzipTest.cc)
|
||||
add_executable(url_codec_test UrlCodecTest.cc)
|
||||
add_executable(url_codec_test UrlCodecTest.cc)
|
||||
add_executable(main_loop_test MainLoopTest.cc)
|
|
@ -0,0 +1,14 @@
|
|||
#include <drogon/drogon.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::thread([]() {
|
||||
drogon::app().getLoop()->runEvery(1, []() {
|
||||
std::cout << "!" << std::endl;
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
drogon::app().run();
|
||||
}
|
Loading…
Reference in New Issue