mirror of
https://github.com/hoytech/strfry.git
synced 2025-06-19 09:36:43 +00:00
limit on max number of concurrent REQs
This commit is contained in:
@ -140,6 +140,9 @@ config:
|
|||||||
- name: relay__maxFilterLimit
|
- name: relay__maxFilterLimit
|
||||||
desc: "Maximum records that can be returned per filter"
|
desc: "Maximum records that can be returned per filter"
|
||||||
default: 500
|
default: 500
|
||||||
|
- name: relay__maxSubsPerConnection
|
||||||
|
desc: "Maximum number of subscriptions (concurrent REQs) a connection can have open at any time"
|
||||||
|
default: 20
|
||||||
|
|
||||||
- name: relay__compression__enabled
|
- name: relay__compression__enabled
|
||||||
desc: "Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU"
|
desc: "Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU"
|
||||||
|
@ -40,7 +40,7 @@ struct ActiveMonitors : NonCopyable {
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void addSub(lmdb::txn &txn, Subscription &&sub, uint64_t currEventId) {
|
bool addSub(lmdb::txn &txn, Subscription &&sub, uint64_t currEventId) {
|
||||||
if (sub.latestEventId != currEventId) throw herr("sub not up to date");
|
if (sub.latestEventId != currEventId) throw herr("sub not up to date");
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -51,10 +51,15 @@ struct ActiveMonitors : NonCopyable {
|
|||||||
auto res = conns.try_emplace(sub.connId);
|
auto res = conns.try_emplace(sub.connId);
|
||||||
auto &connMonitors = res.first->second;
|
auto &connMonitors = res.first->second;
|
||||||
|
|
||||||
|
if (connMonitors.size() >= cfg().relay__maxSubsPerConnection) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto subId = sub.subId;
|
auto subId = sub.subId;
|
||||||
auto *m = &connMonitors.try_emplace(subId, sub).first->second;
|
auto *m = &connMonitors.try_emplace(subId, sub).first->second;
|
||||||
|
|
||||||
installLookups(m, currEventId);
|
installLookups(m, currEventId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeSub(uint64_t connId, const SubId &subId) {
|
void removeSub(uint64_t connId, const SubId &subId) {
|
||||||
|
@ -28,9 +28,11 @@ void RelayServer::runReqMonitor(ThreadPool<MsgReqMonitor>::Thread &thr) {
|
|||||||
|
|
||||||
for (auto &newMsg : newMsgs) {
|
for (auto &newMsg : newMsgs) {
|
||||||
if (auto msg = std::get_if<MsgReqMonitor::NewSub>(&newMsg.msg)) {
|
if (auto msg = std::get_if<MsgReqMonitor::NewSub>(&newMsg.msg)) {
|
||||||
|
auto connId = msg->sub.connId;
|
||||||
|
|
||||||
env.foreach_Event(txn, [&](auto &ev){
|
env.foreach_Event(txn, [&](auto &ev){
|
||||||
if (msg->sub.filterGroup.doesMatch(ev.flat_nested())) {
|
if (msg->sub.filterGroup.doesMatch(ev.flat_nested())) {
|
||||||
sendEvent(msg->sub.connId, msg->sub.subId, getEventJson(txn, decomp, ev.primaryKeyId));
|
sendEvent(connId, msg->sub.subId, getEventJson(txn, decomp, ev.primaryKeyId));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -38,7 +40,9 @@ void RelayServer::runReqMonitor(ThreadPool<MsgReqMonitor>::Thread &thr) {
|
|||||||
|
|
||||||
msg->sub.latestEventId = latestEventId;
|
msg->sub.latestEventId = latestEventId;
|
||||||
|
|
||||||
monitors.addSub(txn, std::move(msg->sub), latestEventId);
|
if (!monitors.addSub(txn, std::move(msg->sub), latestEventId)) {
|
||||||
|
sendNoticeError(connId, std::string("too many concurrent REQs"));
|
||||||
|
}
|
||||||
} else if (auto msg = std::get_if<MsgReqMonitor::RemoveSub>(&newMsg.msg)) {
|
} else if (auto msg = std::get_if<MsgReqMonitor::RemoveSub>(&newMsg.msg)) {
|
||||||
monitors.removeSub(msg->connId, msg->subId);
|
monitors.removeSub(msg->connId, msg->subId);
|
||||||
} else if (auto msg = std::get_if<MsgReqMonitor::CloseConn>(&newMsg.msg)) {
|
} else if (auto msg = std::get_if<MsgReqMonitor::CloseConn>(&newMsg.msg)) {
|
||||||
|
@ -9,7 +9,7 @@ struct ActiveQueries : NonCopyable {
|
|||||||
flat_hash_map<uint64_t, ConnQueries> conns; // connId -> subId -> DBScanQuery*
|
flat_hash_map<uint64_t, ConnQueries> conns; // connId -> subId -> DBScanQuery*
|
||||||
std::deque<DBScanQuery*> running;
|
std::deque<DBScanQuery*> running;
|
||||||
|
|
||||||
void addSub(lmdb::txn &txn, Subscription &&sub) {
|
bool addSub(lmdb::txn &txn, Subscription &&sub) {
|
||||||
sub.latestEventId = getMostRecentLevId(txn);
|
sub.latestEventId = getMostRecentLevId(txn);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -20,10 +20,16 @@ struct ActiveQueries : NonCopyable {
|
|||||||
auto res = conns.try_emplace(sub.connId);
|
auto res = conns.try_emplace(sub.connId);
|
||||||
auto &connQueries = res.first->second;
|
auto &connQueries = res.first->second;
|
||||||
|
|
||||||
|
if (connQueries.size() >= cfg().relay__maxSubsPerConnection) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DBScanQuery *q = new DBScanQuery(sub);
|
DBScanQuery *q = new DBScanQuery(sub);
|
||||||
|
|
||||||
connQueries.try_emplace(q->sub.subId, q);
|
connQueries.try_emplace(q->sub.subId, q);
|
||||||
running.push_front(q);
|
running.push_front(q);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBScanQuery *findQuery(uint64_t connId, const SubId &subId) {
|
DBScanQuery *findQuery(uint64_t connId, const SubId &subId) {
|
||||||
@ -98,7 +104,12 @@ void RelayServer::runReqWorker(ThreadPool<MsgReqWorker>::Thread &thr) {
|
|||||||
|
|
||||||
for (auto &newMsg : newMsgs) {
|
for (auto &newMsg : newMsgs) {
|
||||||
if (auto msg = std::get_if<MsgReqWorker::NewSub>(&newMsg.msg)) {
|
if (auto msg = std::get_if<MsgReqWorker::NewSub>(&newMsg.msg)) {
|
||||||
queries.addSub(txn, std::move(msg->sub));
|
auto connId = msg->sub.connId;
|
||||||
|
|
||||||
|
if (!queries.addSub(txn, std::move(msg->sub))) {
|
||||||
|
sendNoticeError(connId, std::string("too many concurrent REQs"));
|
||||||
|
}
|
||||||
|
|
||||||
queries.process(this, txn);
|
queries.process(this, txn);
|
||||||
} else if (auto msg = std::get_if<MsgReqWorker::RemoveSub>(&newMsg.msg)) {
|
} else if (auto msg = std::get_if<MsgReqWorker::RemoveSub>(&newMsg.msg)) {
|
||||||
queries.removeSub(msg->connId, msg->subId);
|
queries.removeSub(msg->connId, msg->subId);
|
||||||
|
@ -52,6 +52,9 @@ relay {
|
|||||||
# Maximum records that can be returned per filter
|
# Maximum records that can be returned per filter
|
||||||
maxFilterLimit = 500
|
maxFilterLimit = 500
|
||||||
|
|
||||||
|
# Maximum number of subscriptions (concurrent REQs) a connection can have open at any time
|
||||||
|
maxSubsPerConnection = 2
|
||||||
|
|
||||||
compression {
|
compression {
|
||||||
# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)
|
# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)
|
||||||
enabled = true
|
enabled = true
|
||||||
|
Reference in New Issue
Block a user