Closed jphz closed 1 month ago
Appears when querying a large amount of data.
boost::mysql::pooled_connection connection;
while (true) {
connection = _gameDB->async_get_connection(yield[ec]);
if (!ec) {
break;
}
continue;
}
···
Is there any other way to solve it?
This means that the connection pool has reached its upper limit and all connections are now in use. You can solve this in two ways:
pooled_connection
object returned by async_get_connection
is destroyed.If you post a code snippet with more info, I can provide some help on the second point.
boost::asio::spawn(_threadPool, [this, self = shared_from_this(), conn = conn->shared_from_this(),
packet = packet->shared_from_this()](boost::asio::yield_context yield) {
auto msgID = packet->readUInt16();
uint64_t sn = packet->getParam();
auto sql = packet->readString();
LOG_DEBUG("DBServer::onReqMySQLQueryBySession type:{} sn:{} sql:{}", conn->getType(), sn, sql);
POP_PACKET(sendPacket, Proto::REP_MYSQL_QUERY_BY_SESSION);
sendPacket->setParam(sn);
sendPacket->writeUInt16(msgID);
boost::system::error_code ec{};
boost::mysql::pooled_connection connection;
while (true) {
connection = _gameDB->async_get_connection(yield[ec]);
if (!ec) {
break;
}
LOG_ERROR("DBServer::onReqMySQLQueryBySession type:{} sn:{} code:{} error:{}", conn->getType(), sn,
ec.value(), ec.message());
continue;
}
boost::mysql::results results{};
connection->async_execute(sql, results, yield[ec]);
if (ec) {
LOG_ERROR("DBServer::onReqMySQLQueryBySession type:{} sn:{} code:{} error:{}", conn->getType(), sn,
ec.value(), ec.message());
conn->sendMsg(sendPacket);
return;
}
if (!serialize(results, sendPacket)) {
sendPacket->reset();
sendPacket->setMsgID(Proto::REP_MYSQL_QUERY_BY_SESSION);
sendPacket->setParam(sn);
sendPacket->writeUInt16(msgID);
}
conn->sendMsg(sendPacket);
});
Do need any additional processing?
Are the conn->sendMsg
calls blocking?
void Connection::sendMsg(Packet::Ptr packet) {
boost::asio::post(_stream.get_executor(),
[this, self = shared_from_this(), packet = packet->shared_from_this()]() {
onPack(packet);
});
}
Not blocking
Does onPack
call any blocking function (like network read or write)?
How many concurrent requests is your application receiving?
If you don't need any timeout, you can replace this
while (true) {
connection = _gameDB->async_get_connection(yield[ec]);
if (!ec) {
break;
}
LOG_ERROR("DBServer::onReqMySQLQueryBySession type:{} sn:{} code:{} error:{}", conn->getType(), sn,
ec.value(), ec.message());
continue;
}
by simply
// A zero timeout means "wait indefinitely until a connection is available"
connection = _gameDB->async_get_connection(std::chrono::seconds(0), yield[ec]);
Thank you very much.
If the rest of your application uses blocking functions and doesn't integrate well with Asio's async model, you may consider using this code to get a synchronous equivalent of asnc_get_connection
.
My code is all asynchronous, except for parsing network packets, which takes some time.
Then you should be fine with what you are doing. Try increasing the number of allowed connections to the server if you get too much latency.
Yes, I need to increase the number of connections. The previous number of connections was too small.
I have encountered this problem, how can I make it work properly.