From ea35b62373cf8795593dc633ff142426e2cbca16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Jul 2020 10:47:38 +0300 Subject: [PATCH] MXS-619: Delay destruction of the client DCB By delaying the processing of a client DCB in the zombie queue, we avoid initiating the shutdown process of the backend DCBs too early. This solves the problem of the previous implementation where the session shutdown proceeded too far before the delaying process started. --- server/core/routingworker.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/server/core/routingworker.cc b/server/core/routingworker.cc index 63462fa06..6b578ac75 100644 --- a/server/core/routingworker.cc +++ b/server/core/routingworker.cc @@ -38,6 +38,7 @@ #include "internal/modules.hh" #include "internal/poll.hh" #include "internal/service.hh" +#include "internal/session.hh" #define WORKER_ABSENT_ID -1 @@ -559,6 +560,7 @@ void RoutingWorker::register_zombie(DCB* pDcb) void RoutingWorker::delete_zombies() { + Zombies slow_zombies; // An algorithm cannot be used, as the final closing of a DCB may cause // other DCBs to be registered in the zombie queue. @@ -567,8 +569,30 @@ void RoutingWorker::delete_zombies() DCB* pDcb = m_zombies.back(); m_zombies.pop_back(); - dcb_final_close(pDcb); + bool can_close = true; + + if (pDcb->role == DCB::Role::CLIENT) + { + // Check if any of the backend DCBs isn't ready to be closed. If so, delay the closing of the + // client DCB until the backend connections have fully established and finished authenticating. + const auto& dcbs = static_cast(pDcb->session)->dcb_set(); + can_close = std::all_of(dcbs.begin(), dcbs.end(), can_close_dcb); + } + + if (can_close) + { + MXS_DEBUG("Ready to close session %lu", pDcb->session->ses_id); + dcb_final_close(pDcb); + } + else + { + MXS_DEBUG("Delaying destruction of session %lu", pDcb->session->ses_id); + slow_zombies.push_back(pDcb); + } } + + mxb_assert(m_zombies.empty()); + m_zombies.insert(m_zombies.end(), slow_zombies.begin(), slow_zombies.end()); } bool RoutingWorker::pre_run()