Add the getCurrentThreadIndex() method (#264)
This commit is contained in:
parent
5605d7d351
commit
f9d7f589a2
|
@ -910,6 +910,22 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
/// Return true is drogon supports SSL(https)
|
||||
virtual bool supportSSL() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the Current Thread Index whose range is [0, the total number
|
||||
* of IO threads]
|
||||
*
|
||||
* @return size_t If the current thread is the main thread, the number of
|
||||
* the IO threads is returned. If the current thread is a network IO thread,
|
||||
* the index of it in the range [0, the number of IO threads) is returned.
|
||||
* otherwise the maximum value of type size_t is returned.
|
||||
*
|
||||
* @note Basically this method is used for storing thread-related various in
|
||||
* an array and users can use indexes returned by this method to access
|
||||
* them. This is much faster than using a map. If the array is properly
|
||||
* initialized at the beginning, users can access it without locks.
|
||||
*/
|
||||
virtual size_t getCurrentThreadIndex() const = 0;
|
||||
|
||||
private:
|
||||
virtual void registerHttpController(
|
||||
const std::string &pathPattern,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <drogon/orm/DbClient.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <trantor/utils/NonCopyable.h>
|
||||
#include <trantor/net/EventLoop.h>
|
||||
#include <string>
|
||||
|
@ -35,11 +36,11 @@ class DbClientManager : public trantor::NonCopyable
|
|||
|
||||
DbClientPtr getFastDbClient(const std::string &name)
|
||||
{
|
||||
assert(_dbFastClientsMap[name].find(
|
||||
trantor::EventLoop::getEventLoopOfCurrentThread()) !=
|
||||
_dbFastClientsMap[name].end());
|
||||
return _dbFastClientsMap
|
||||
[name][trantor::EventLoop::getEventLoopOfCurrentThread()];
|
||||
auto index = drogon::app().getCurrentThreadIndex();
|
||||
auto iter = _dbFastClientsMap.find(name);
|
||||
assert(iter != _dbFastClientsMap.end());
|
||||
assert(index < iter->second.size());
|
||||
return iter->second[index];
|
||||
}
|
||||
void createDbClient(const std::string &dbType,
|
||||
const std::string &host,
|
||||
|
@ -63,8 +64,7 @@ class DbClientManager : public trantor::NonCopyable
|
|||
size_t _connectionNumber;
|
||||
};
|
||||
std::vector<DbInfo> _dbInfos;
|
||||
std::map<std::string, std::map<trantor::EventLoop *, orm::DbClientPtr>>
|
||||
_dbFastClientsMap;
|
||||
std::map<std::string, std::vector<orm::DbClientPtr>> _dbFastClientsMap;
|
||||
};
|
||||
} // namespace orm
|
||||
} // namespace drogon
|
||||
|
|
|
@ -397,8 +397,14 @@ void HttpAppFrameworkImpl::run()
|
|||
_sslKeyPath,
|
||||
_threadNum,
|
||||
_syncAdvices);
|
||||
// A fast database client instance should be created in the main event loop,
|
||||
// so put the main loop into ioLoops.
|
||||
assert(ioLoops.size() == _threadNum);
|
||||
for (size_t i=0; i < _threadNum; ++i)
|
||||
{
|
||||
ioLoops[i]->setIndex(i);
|
||||
}
|
||||
getLoop()->setIndex(_threadNum);
|
||||
// A fast database client instance should be created in the main event
|
||||
// loop, so put the main loop into ioLoops.
|
||||
ioLoops.push_back(getLoop());
|
||||
_dbClientManagerPtr->createDbClients(ioLoops);
|
||||
ioLoops.pop_back();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
|
@ -392,6 +393,16 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual size_t getCurrentThreadIndex() const override
|
||||
{
|
||||
auto *loop = trantor::EventLoop::getEventLoopOfCurrentThread();
|
||||
if (loop)
|
||||
{
|
||||
return loop->index();
|
||||
}
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void registerHttpController(
|
||||
const std::string &pathPattern,
|
||||
|
|
|
@ -54,11 +54,7 @@ void HttpControllersRouter::init(
|
|||
{
|
||||
binder->_filters =
|
||||
filters_function::createFilters(binder->_filterNames);
|
||||
for (auto ioloop : ioLoops)
|
||||
{
|
||||
binder->_responsePtrMap[ioloop] =
|
||||
std::shared_ptr<HttpResponse>();
|
||||
}
|
||||
binder->_responseCache.resize(ioLoops.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +340,7 @@ void HttpControllersRouter::doControllerHandler(
|
|||
if (ctrlBinderPtr->_hasCachedResponse)
|
||||
{
|
||||
HttpResponsePtr &responsePtr =
|
||||
ctrlBinderPtr->_responsePtrMap[req->getLoop()];
|
||||
ctrlBinderPtr->_responseCache[req->getLoop()->index()];
|
||||
if (responsePtr &&
|
||||
(responsePtr->expiredTime() == 0 ||
|
||||
(trantor::Date::now() <
|
||||
|
@ -405,13 +401,13 @@ void HttpControllersRouter::doControllerHandler(
|
|||
auto loop = req->getLoop();
|
||||
if (loop->isInLoopThread())
|
||||
{
|
||||
ctrlBinderPtr->_responsePtrMap[loop] = resp;
|
||||
ctrlBinderPtr->_responseCache[loop->index()] = resp;
|
||||
ctrlBinderPtr->_hasCachedResponse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
req->getLoop()->queueInLoop([loop, resp, ctrlBinderPtr]() {
|
||||
ctrlBinderPtr->_responsePtrMap[loop] = resp;
|
||||
ctrlBinderPtr->_responseCache[loop->index()] = resp;
|
||||
ctrlBinderPtr->_hasCachedResponse = true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -78,8 +78,7 @@ class HttpControllersRouter : public trantor::NonCopyable
|
|||
std::vector<std::shared_ptr<HttpFilterBase>> _filters;
|
||||
std::vector<size_t> _parameterPlaces;
|
||||
std::map<std::string, size_t> _queryParametersPlaces;
|
||||
std::map<trantor::EventLoop *, std::shared_ptr<HttpResponse>>
|
||||
_responsePtrMap;
|
||||
std::vector<std::shared_ptr<HttpResponse>> _responseCache;
|
||||
bool _isCORS = false;
|
||||
bool _hasCachedResponse = false;
|
||||
};
|
||||
|
|
|
@ -197,7 +197,7 @@ void HttpSimpleControllersRouter::doControllerHandler(
|
|||
if (ctrlBinderPtr->_hasCachedResponse)
|
||||
{
|
||||
HttpResponsePtr &responsePtr =
|
||||
ctrlBinderPtr->_responsePtrMap[req->getLoop()];
|
||||
ctrlBinderPtr->_responseCache[req->getLoop()->index()];
|
||||
if (responsePtr &&
|
||||
(responsePtr->expiredTime() == 0 ||
|
||||
(trantor::Date::now() < responsePtr->creationDate().after(
|
||||
|
@ -224,13 +224,14 @@ void HttpSimpleControllersRouter::doControllerHandler(
|
|||
|
||||
if (loop->isInLoopThread())
|
||||
{
|
||||
ctrlBinderPtr->_responsePtrMap[loop] = resp;
|
||||
ctrlBinderPtr->_responseCache[loop->index()] = resp;
|
||||
ctrlBinderPtr->_hasCachedResponse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
loop->queueInLoop([loop, resp, &ctrlBinderPtr]() {
|
||||
ctrlBinderPtr->_responsePtrMap[loop] = resp;
|
||||
ctrlBinderPtr->_responseCache[loop->index()] =
|
||||
resp;
|
||||
ctrlBinderPtr->_hasCachedResponse = true;
|
||||
});
|
||||
}
|
||||
|
@ -284,10 +285,7 @@ void HttpSimpleControllersRouter::init(
|
|||
{
|
||||
binder->_filters =
|
||||
filters_function::createFilters(binder->_filterNames);
|
||||
for (auto ioloop : ioLoops)
|
||||
{
|
||||
binder->_responsePtrMap[ioloop] = nullptr;
|
||||
}
|
||||
binder->_responseCache.resize(ioLoops.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,8 +94,7 @@ class HttpSimpleControllersRouter : public trantor::NonCopyable
|
|||
std::string _controllerName;
|
||||
std::vector<std::string> _filterNames;
|
||||
std::vector<std::shared_ptr<HttpFilterBase>> _filters;
|
||||
std::map<trantor::EventLoop *, std::shared_ptr<HttpResponse>>
|
||||
_responsePtrMap;
|
||||
std::vector<std::shared_ptr<HttpResponse>> _responseCache;
|
||||
bool _isCORS = false;
|
||||
bool _hasCachedResponse = false;
|
||||
};
|
||||
|
|
|
@ -778,8 +778,8 @@ std::string gzipDecompress(const char *data, const size_t ndata)
|
|||
|
||||
char *getHttpFullDate(const trantor::Date &date)
|
||||
{
|
||||
static __thread int64_t lastSecond = 0;
|
||||
static __thread char lastTimeString[128] = {0};
|
||||
static thread_local int64_t lastSecond = 0;
|
||||
static thread_local char lastTimeString[128] = {0};
|
||||
auto nowSecond = date.microSecondsSinceEpoch() / MICRO_SECONDS_PRE_SEC;
|
||||
if (nowSecond == lastSecond)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../../lib/src/DbClientManager.h"
|
||||
#include "DbClientLockFree.h"
|
||||
#include <drogon/config.h>
|
||||
#include <drogon/HttpAppFramework.h>
|
||||
#include <drogon/utils/Utilities.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -30,6 +31,7 @@ void DbClientManager::createDbClients(
|
|||
{
|
||||
if (dbInfo._isFast)
|
||||
{
|
||||
_dbFastClientsMap[dbInfo._name].resize(ioloops.size());
|
||||
for (auto *loop : ioloops)
|
||||
{
|
||||
if (dbInfo._dbType == drogon::orm::ClientType::Sqlite3)
|
||||
|
@ -40,7 +42,7 @@ void DbClientManager::createDbClients(
|
|||
if (dbInfo._dbType == drogon::orm::ClientType::PostgreSQL ||
|
||||
dbInfo._dbType == drogon::orm::ClientType::Mysql)
|
||||
{
|
||||
_dbFastClientsMap[dbInfo._name][loop] =
|
||||
_dbFastClientsMap[dbInfo._name][loop->index()] =
|
||||
std::shared_ptr<drogon::orm::DbClient>(
|
||||
new drogon::orm::DbClientLockFree(
|
||||
dbInfo._connectionInfo,
|
||||
|
|
2
trantor
2
trantor
|
@ -1 +1 @@
|
|||
Subproject commit e95f82d3090f81b4f5b7610b4e0e6e609c734509
|
||||
Subproject commit 99ba85bd4c252b7003e73eef50c862d51c23e4e0
|
Loading…
Reference in New Issue