mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
update session management, hopefully at least report every session dead lock, maybe even prevent any session dead lock
This commit is contained in:
parent
53d1309517
commit
f4e55f78c1
@ -14,7 +14,7 @@ SessionManager* SessionManager::getInstance()
|
||||
}
|
||||
|
||||
SessionManager::SessionManager()
|
||||
: mInitalized(false)
|
||||
: mInitalized(false), mDeadLockedSessionCount(0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -89,6 +89,7 @@ void SessionManager::deinitalize()
|
||||
delete mValidations[i];
|
||||
}
|
||||
|
||||
printf("[SessionManager::deinitalize] count of dead locked sessions: %d\n", mDeadLockedSessionCount);
|
||||
|
||||
mInitalized = false;
|
||||
mWorkingMutex.unlock();
|
||||
@ -277,6 +278,7 @@ bool SessionManager::releaseSession(int requestHandleSession)
|
||||
|
||||
bool SessionManager::isExist(int requestHandleSession)
|
||||
{
|
||||
static const char* function_name = "SessionManager::isExist";
|
||||
if (!mInitalized) {
|
||||
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||
return false;
|
||||
@ -294,7 +296,13 @@ bool SessionManager::isExist(int requestHandleSession)
|
||||
auto it = mRequestSessionMap.find(requestHandleSession);
|
||||
if (it != mRequestSessionMap.end()) {
|
||||
result = true;
|
||||
if (!it->second->isActive()) {
|
||||
int iResult = it->second->isActive();
|
||||
if (-1 == iResult) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new Error(function_name, "session return locked"));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
if (0 == iResult) {
|
||||
printf("[SessionManager::isExist] session isn't active\n");
|
||||
}
|
||||
}
|
||||
@ -321,6 +329,7 @@ Session* SessionManager::getSession(const Poco::Net::HTTPServerRequest& request)
|
||||
|
||||
Session* SessionManager::getSession(int handle)
|
||||
{
|
||||
static const char* function_name = "SessionManager::getSession";
|
||||
if (!mInitalized) {
|
||||
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||
return nullptr;
|
||||
@ -339,7 +348,15 @@ Session* SessionManager::getSession(int handle)
|
||||
auto it = mRequestSessionMap.find(handle);
|
||||
if (it != mRequestSessionMap.end()) {
|
||||
result = it->second;
|
||||
if (!result->isActive()) {
|
||||
int iResult = result->isActive();
|
||||
if (iResult == -1) {
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new Error(function_name, "session is locked"));
|
||||
em->sendErrorsAsEmail();
|
||||
mWorkingMutex.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
if (0 == iResult) {
|
||||
//printf("[SessionManager::getSession] session isn't active\n");
|
||||
mWorkingMutex.unlock();
|
||||
return nullptr;
|
||||
@ -382,6 +399,14 @@ Session* SessionManager::findByUserId(int userId)
|
||||
}
|
||||
//mWorkingMutex.lock();
|
||||
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||
while (it->second->isDeadLocked())
|
||||
{
|
||||
it = mRequestSessionMap.erase(it);
|
||||
mDeadLockedSessionCount++;
|
||||
auto em = ErrorManager::getInstance();
|
||||
em->addError(new ParamError("SessionManager::findByUserId", "new dead locked session found, sum dead lock sessions:", mDeadLockedSessionCount));
|
||||
em->sendErrorsAsEmail();
|
||||
}
|
||||
auto user = it->second->getNewUser();
|
||||
auto em = ErrorManager::getInstance();
|
||||
if(!user) continue;
|
||||
@ -422,6 +447,10 @@ std::vector<Session*> SessionManager::findAllByUserId(int userId)
|
||||
}
|
||||
//mWorkingMutex.lock();
|
||||
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||
if (it->second->isDeadLocked()) {
|
||||
it = mRequestSessionMap.erase(it);
|
||||
mDeadLockedSessionCount++;
|
||||
}
|
||||
auto user = it->second->getNewUser();
|
||||
if (userId == user->getModel()->getID()) {
|
||||
//return it->second;
|
||||
@ -448,6 +477,10 @@ Session* SessionManager::findByEmail(const std::string& email)
|
||||
}
|
||||
//mWorkingMutex.lock();
|
||||
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||
if (it->second->isDeadLocked()) {
|
||||
it = mRequestSessionMap.erase(it);
|
||||
mDeadLockedSessionCount++;
|
||||
}
|
||||
auto user = it->second->getNewUser();
|
||||
if (email == user->getModel()->getEmail()) {
|
||||
return it->second;
|
||||
@ -477,9 +510,11 @@ void SessionManager::checkTimeoutSession()
|
||||
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||
|
||||
if (it->second->tryLock()) {
|
||||
it->second->unlock();
|
||||
// skip already disabled sessions
|
||||
if (!it->second->isActive()) continue;
|
||||
if (!it->second->isActive()) {
|
||||
it->second->unlock();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// skip dead locked sessions
|
||||
@ -487,6 +522,7 @@ void SessionManager::checkTimeoutSession()
|
||||
}
|
||||
|
||||
Poco::Timespan timeElapsed(now - it->second->getLastActivity());
|
||||
it->second->unlock();
|
||||
if (timeElapsed > timeout) {
|
||||
toRemove.push(it->first);
|
||||
}
|
||||
@ -513,7 +549,11 @@ void SessionManager::deleteLoginCookies(Poco::Net::HTTPServerRequest& request, P
|
||||
if (activeSession) {
|
||||
try {
|
||||
int session_id = atoi(it->second.data());
|
||||
if (session_id == activeSession->getHandle()) continue;
|
||||
if (activeSession->tryLock()) {
|
||||
bool session_id_is_handle = session_id == activeSession->getHandle();
|
||||
activeSession->unlock();
|
||||
if (session_id_is_handle) continue;
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
@ -84,6 +84,7 @@ protected:
|
||||
// sessions storage
|
||||
std::map<int, Session*> mRequestSessionMap;
|
||||
std::stack<int> mEmptyRequestStack;
|
||||
int mDeadLockedSessionCount;
|
||||
|
||||
bool mInitalized;
|
||||
|
||||
|
||||
@ -131,6 +131,47 @@ void Session::reset()
|
||||
//printf("[Session::reset] finished\n");
|
||||
}
|
||||
|
||||
int Session::isActive()
|
||||
{
|
||||
int ret = 0;
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
catch (Poco::TimeoutException &ex) {
|
||||
return -1;
|
||||
}
|
||||
ret = (int)mActive;
|
||||
unlock();
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
bool Session::isDeadLocked()
|
||||
{
|
||||
try {
|
||||
mWorkMutex.tryLock(200);
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
catch (Poco::Exception& ex) {
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::setActive(bool active)
|
||||
{
|
||||
try {
|
||||
mWorkMutex.tryLock(100);
|
||||
}
|
||||
catch (Poco::TimeoutException &ex) {
|
||||
return false;
|
||||
}
|
||||
mActive = active;
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Session::updateTimeout()
|
||||
{
|
||||
lock("Session::updateTimeout");
|
||||
|
||||
@ -162,8 +162,14 @@ public:
|
||||
return mEmailVerificationCodeObject->getModel()->getType();
|
||||
}
|
||||
|
||||
inline bool isActive() { bool bret = false; lock("Session::isActive"); bret = mActive; unlock(); return bret; }
|
||||
inline void setActive(bool active) { lock("Sessions::setActive"); mActive = active; unlock(); }
|
||||
//! \return -1 if session is locked
|
||||
//! \return 1 if session is active
|
||||
//! \return 0
|
||||
int isActive();
|
||||
//! \return false if session is locked
|
||||
bool setActive(bool active);
|
||||
|
||||
bool isDeadLocked();
|
||||
|
||||
inline Poco::DateTime getLastActivity() { return mLastActivity; }
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user