0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-27 19:28:52 +02:00

modules/s_listen: Add accept flow control mechanism.

This commit is contained in:
Jason Volk 2019-04-15 22:03:26 -07:00
parent 450e31e333
commit 2b759963bd
2 changed files with 46 additions and 4 deletions

View file

@ -415,6 +415,8 @@ try
assert(client->reqctx);
assert(client->reqctx == ctx::current);
client->reqctx = nullptr;
if(client::pool.avail() <= 1)
client::dock.notify_all();
}};
#ifdef RB_DEBUG

View file

@ -201,6 +201,35 @@ load_listener(const m::event &event)
return load_listener(name, opts);
}
ctx::context
_listener_allow
{
"listener allow", 32_KiB, context::POST, []
{
while(1)
{
client::dock.wait([]
{
return !client::pool.avail();
});
client::dock.wait([]
{
if(!client::pool.avail())
return false;
if(client::map.size() >= size_t(client::settings::max_client))
return false;
return true;
});
for(auto &listener : listeners)
allow(listener);
}
}
};
static bool
_listener_proffer(net::listener &listener,
const net::ipport &ipport)
@ -218,10 +247,6 @@ _listener_proffer(net::listener &listener,
return false;
}
// Sets the asynchronous handler for the next accept. We can play with
// delaying this call under certain conditions to provide flow control.
allow(listener);
if(unlikely(client::map.size() >= size_t(client::settings::max_client)))
{
log::warning
@ -234,6 +259,21 @@ _listener_proffer(net::listener &listener,
return false;
}
if(unlikely(!client::pool.avail()))
{
log::dwarning
{
"Refusing to add new client from %s because request pool exhausted.",
string(strbuf, ipport),
};
return false;
}
// Sets the asynchronous handler for the next accept. We can play with
// delaying this call under certain conditions to provide flow control.
allow(listener);
if(client::count(ipport) >= size_t(client::settings::max_client_per_peer))
{
log::dwarning