mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
committed by
Alex Kremer
parent
164387cab0
commit
4947a83696
@@ -41,10 +41,16 @@ CoroutineGroup::~CoroutineGroup()
|
|||||||
ASSERT(childrenCounter_ == 0, "CoroutineGroup is destroyed without waiting for child coroutines to finish");
|
ASSERT(childrenCounter_ == 0, "CoroutineGroup is destroyed without waiting for child coroutines to finish");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CoroutineGroup::canSpawn() const
|
||||||
|
{
|
||||||
|
return not maxChildren_.has_value() or childrenCounter_ < *maxChildren_;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CoroutineGroup::spawn(boost::asio::yield_context yield, std::function<void(boost::asio::yield_context)> fn)
|
CoroutineGroup::spawn(boost::asio::yield_context yield, std::function<void(boost::asio::yield_context)> fn)
|
||||||
{
|
{
|
||||||
if (maxChildren_.has_value() && childrenCounter_ >= *maxChildren_)
|
if (not canSpawn())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
++childrenCounter_;
|
++childrenCounter_;
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
~CoroutineGroup();
|
~CoroutineGroup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if a new coroutine can be spawned (i.e. there is space for a new coroutine in the group)
|
||||||
|
*
|
||||||
|
* @return true If a new coroutine can be spawned. false if the maximum number of coroutines has been reached
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
canSpawn() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Spawn a new coroutine in the group
|
* @brief Spawn a new coroutine in the group
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -218,21 +218,21 @@ ConnectionHandler::parallelRequestResponseLoop(Connection& connection, boost::as
|
|||||||
closeConnectionGracefully &= closeGracefully;
|
closeConnectionGracefully &= closeGracefully;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (tasksGroup.canSpawn()) {
|
||||||
bool const spawnSuccess = tasksGroup.spawn(
|
bool const spawnSuccess = tasksGroup.spawn(
|
||||||
yield, // spawn on the same strand
|
yield, // spawn on the same strand
|
||||||
[this, &stop, &closeConnectionGracefully, &connection, request = std::move(expectedRequest).value()](
|
[this, &stop, &closeConnectionGracefully, &connection, request = std::move(expectedRequest).value()](
|
||||||
boost::asio::yield_context innerYield
|
boost::asio::yield_context innerYield
|
||||||
) mutable {
|
) mutable {
|
||||||
auto maybeCloseConnectionGracefully = processRequest(connection, request, innerYield);
|
auto maybeCloseConnectionGracefully = processRequest(connection, request, innerYield);
|
||||||
if (maybeCloseConnectionGracefully.has_value()) {
|
if (maybeCloseConnectionGracefully.has_value()) {
|
||||||
stop = true;
|
stop = true;
|
||||||
closeConnectionGracefully &= maybeCloseConnectionGracefully.value();
|
closeConnectionGracefully &= maybeCloseConnectionGracefully.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
);
|
ASSERT(spawnSuccess, "The coroutine was expected to be spawned");
|
||||||
|
} else {
|
||||||
if (not spawnSuccess) {
|
|
||||||
connection.send(
|
connection.send(
|
||||||
Response{
|
Response{
|
||||||
boost::beast::http::status::too_many_requests,
|
boost::beast::http::status::too_many_requests,
|
||||||
|
|||||||
@@ -33,10 +33,12 @@
|
|||||||
#include <boost/beast/core/flat_buffer.hpp>
|
#include <boost/beast/core/flat_buffer.hpp>
|
||||||
#include <boost/beast/core/stream_traits.hpp>
|
#include <boost/beast/core/stream_traits.hpp>
|
||||||
#include <boost/beast/core/tcp_stream.hpp>
|
#include <boost/beast/core/tcp_stream.hpp>
|
||||||
|
#include <boost/beast/http.hpp>
|
||||||
#include <boost/beast/http/field.hpp>
|
#include <boost/beast/http/field.hpp>
|
||||||
#include <boost/beast/http/message.hpp>
|
#include <boost/beast/http/message.hpp>
|
||||||
#include <boost/beast/http/string_body.hpp>
|
#include <boost/beast/http/string_body.hpp>
|
||||||
#include <boost/beast/http/verb.hpp>
|
#include <boost/beast/http/verb.hpp>
|
||||||
|
#include <boost/beast/http/write.hpp>
|
||||||
#include <boost/beast/ssl/ssl_stream.hpp>
|
#include <boost/beast/ssl/ssl_stream.hpp>
|
||||||
#include <boost/beast/version.hpp>
|
#include <boost/beast/version.hpp>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|||||||
@@ -165,3 +165,17 @@ TEST_F(CoroutineGroupTests, TooManyCoroutines)
|
|||||||
callback3_.Call();
|
callback3_.Call();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CoroutineGroupTests, CanSpawn)
|
||||||
|
{
|
||||||
|
EXPECT_CALL(callback1_, Call);
|
||||||
|
|
||||||
|
runSpawn([this](boost::asio::yield_context yield) {
|
||||||
|
CoroutineGroup group{yield, 1};
|
||||||
|
EXPECT_TRUE(group.canSpawn());
|
||||||
|
group.spawn(yield, [&group, this](boost::asio::yield_context) {
|
||||||
|
callback1_.Call();
|
||||||
|
EXPECT_FALSE(group.canSpawn());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user