MXS-3892: Handle multiple pending queries
If the client sends another query before reading the previous result, it was possible that another session finished the shard update and the following query would reuse this result. This would cause the assertion in the delayed call to fail as it assumes the shard would always be empty when it was being called. To correctly handle this case, the delayed call must be the one that moves the session into the normal routing state.
This commit is contained in:
@ -294,6 +294,13 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
|
|||||||
|
|
||||||
if (m_shard.empty() && (m_state & INIT_MAPPING) == 0)
|
if (m_shard.empty() && (m_state & INIT_MAPPING) == 0)
|
||||||
{
|
{
|
||||||
|
if (m_dcid)
|
||||||
|
{
|
||||||
|
// The delayed call is already in place, let it take care of the shard update
|
||||||
|
m_queue.push_back(pPacket);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if another session has managed to update the shard cache
|
// Check if another session has managed to update the shard cache
|
||||||
m_shard = m_router->m_shard_manager.get_shard(m_key, m_config->refresh_min_interval);
|
m_shard = m_router->m_shard_manager.get_shard(m_key, m_config->refresh_min_interval);
|
||||||
|
|
||||||
@ -307,16 +314,13 @@ int32_t SchemaRouterSession::routeQuery(GWBUF* pPacket)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Too many concurrent updates
|
// Wait for the other session to finish its update and reuse that result
|
||||||
|
mxb_assert(m_dcid == 0);
|
||||||
m_queue.push_back(pPacket);
|
m_queue.push_back(pPacket);
|
||||||
|
|
||||||
if (m_dcid == 0)
|
auto worker = mxs::RoutingWorker::get_current();
|
||||||
{
|
m_dcid = worker->delayed_call(1000, &SchemaRouterSession::delay_routing, this);
|
||||||
// Wait for the other session to finish its update
|
MXS_INFO("Waiting for the database mapping to be completed by another session");
|
||||||
auto worker = mxs::RoutingWorker::get_current();
|
|
||||||
m_dcid = worker->delayed_call(1000, &SchemaRouterSession::delay_routing, this);
|
|
||||||
MXS_INFO("Waiting for the database mapping to be completed by another session");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user