Skip to content

Commit 94d1221

Browse files
committed
Fix concurrent bug about session count
1 parent 0adad87 commit 94d1221

File tree

3 files changed

+42
-31
lines changed

3 files changed

+42
-31
lines changed

src/common/session/SessionManager.h

+40-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef COMMON_SESSION_SESSIONMANAGER_H_
77
#define COMMON_SESSION_SESSIONMANAGER_H_
88

9+
#include <folly/RWSpinLock.h>
910
#include <folly/concurrency/ConcurrentHashMap.h>
1011

1112
#include "clients/meta/MetaClient.h"
@@ -23,7 +24,7 @@ namespace nebula {
2324

2425
class SessionCount {
2526
private:
26-
std::atomic<int32_t> count_ = 1;
27+
std::atomic<int32_t> count_{1};
2728

2829
public:
2930
int fetch_add(int step) {
@@ -75,8 +76,45 @@ class SessionManager {
7576
protected:
7677
using SessionPtr = std::shared_ptr<SessionType>;
7778
using SessionCountPtr = std::shared_ptr<SessionCount>;
79+
80+
// Get session count pointer according to key
81+
SessionCountPtr sessionCnt(const std::string& key) {
82+
folly::RWSpinLock::ReadHolder rh(&sessCntLock_);
83+
auto iter = userIpSessionCount_.find(key);
84+
if (iter != userIpSessionCount_.end()) {
85+
return iter->second;
86+
}
87+
return nullptr;
88+
}
89+
90+
// add sessionCount
91+
void addSessionCount(std::string& key) {
92+
auto sessCntPtr = sessionCnt(key);
93+
if (!sessCntPtr) {
94+
folly::RWSpinLock::WriteHolder wh(&sessCntLock_);
95+
auto iter = userIpSessionCount_.emplace(key, std::make_shared<SessionCount>());
96+
sessCntPtr = iter.first->second;
97+
}
98+
sessCntPtr->fetch_add(1);
99+
}
100+
101+
// sub sessionCount
102+
void subSessionCount(std::string& key) {
103+
auto countFindPtr = sessionCnt(key);
104+
if (countFindPtr) {
105+
auto count = countFindPtr->fetch_sub(1);
106+
if (count <= 0) {
107+
folly::RWSpinLock::WriteHolder wh(&sessCntLock_);
108+
userIpSessionCount_.erase(key);
109+
}
110+
}
111+
}
112+
78113
folly::ConcurrentHashMap<SessionID, SessionPtr> activeSessions_;
79-
folly::ConcurrentHashMap<std::string, SessionCountPtr> userIpSessionCount_;
114+
115+
folly::RWSpinLock sessCntLock_;
116+
std::unordered_map<std::string, SessionCountPtr> userIpSessionCount_;
117+
80118
std::unique_ptr<thread::GenericWorker> scavenger_;
81119
meta::MetaClient* metaClient_{nullptr};
82120
HostAddr myAddr_;

src/graph/session/GraphSessionManager.cpp

+2-23
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,8 @@ folly::Future<StatusOr<std::shared_ptr<ClientSession>>> GraphSessionManager::cre
114114
// check the number of sessions per user per ip
115115
std::string key = userName + clientIp;
116116
auto maxSessions = FLAGS_max_sessions_per_ip_per_user;
117-
auto uiscFindPtr = userIpSessionCount_.find(key);
118-
if (uiscFindPtr != userIpSessionCount_.end() && maxSessions > 0 &&
119-
uiscFindPtr->second.get()->get() > maxSessions - 1) {
117+
auto uiscFindPtr = sessionCnt(key);
118+
if (maxSessions > 0 && uiscFindPtr && uiscFindPtr->get() > maxSessions - 1) {
120119
return Status::Error(
121120
"Create Session failed: Too many sessions created from %s by user %s. "
122121
"the threshold is %d. You can change it by modifying '%s' in nebula-graphd.conf",
@@ -362,25 +361,5 @@ void GraphSessionManager::removeSessionFromLocalCache(const std::vector<SessionI
362361
}
363362
}
364363

365-
void GraphSessionManager::addSessionCount(std::string& key) {
366-
auto countFindPtr = userIpSessionCount_.find(key);
367-
if (countFindPtr != userIpSessionCount_.end()) {
368-
countFindPtr->second.get()->fetch_add(1);
369-
} else {
370-
userIpSessionCount_.insert_or_assign(key, std::make_shared<SessionCount>());
371-
}
372-
}
373-
374-
void GraphSessionManager::subSessionCount(std::string& key) {
375-
auto countFindPtr = userIpSessionCount_.find(key);
376-
if (countFindPtr == userIpSessionCount_.end()) {
377-
VLOG(1) << "Session count not found for key: " << key;
378-
return;
379-
}
380-
auto count = countFindPtr->second.get()->fetch_sub(1);
381-
if (count <= 0) {
382-
userIpSessionCount_.erase(countFindPtr);
383-
}
384-
}
385364
} // namespace graph
386365
} // namespace nebula

src/graph/session/GraphSessionManager.h

-6
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,6 @@ class GraphSessionManager final : public SessionManager<ClientSession> {
112112
// Updates session info locally.
113113
// session: ClientSession which will be updated.
114114
void updateSessionInfo(ClientSession* session);
115-
116-
// add sessionCount
117-
void addSessionCount(std::string& key);
118-
119-
// sub sessionCount
120-
void subSessionCount(std::string& key);
121115
};
122116

123117
} // namespace graph

0 commit comments

Comments
 (0)