fix: Clear connection before cancel

This commit is contained in:
Petr Mironychev
2025-11-01 20:51:01 +01:00
parent 1848d44503
commit e7110810f8
4 changed files with 50 additions and 5 deletions

View File

@ -52,7 +52,10 @@ ClientInterface::ClientInterface(
, m_contextManager(new Context::ContextManager(this)) , m_contextManager(new Context::ContextManager(this))
{} {}
ClientInterface::~ClientInterface() = default; ClientInterface::~ClientInterface()
{
cancelRequest();
}
void ClientInterface::sendMessage( void ClientInterface::sendMessage(
const QString &message, const QString &message,
@ -201,6 +204,17 @@ void ClientInterface::clearMessages()
void ClientInterface::cancelRequest() void ClientInterface::cancelRequest()
{ {
QSet<LLMCore::Provider *> providers;
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
if (it.value().provider) {
providers.insert(it.value().provider);
}
}
for (auto *provider : providers) {
disconnect(provider, nullptr, this, nullptr);
}
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
const RequestContext &ctx = it.value(); const RequestContext &ctx = it.value();
if (ctx.provider) { if (ctx.provider) {

View File

@ -51,6 +51,11 @@ LLMClientInterface::LLMClientInterface(
{ {
} }
LLMClientInterface::~LLMClientInterface()
{
handleCancelRequest();
}
Utils::FilePath LLMClientInterface::serverDeviceTemplate() const Utils::FilePath LLMClientInterface::serverDeviceTemplate() const
{ {
return "QodeAssist"; return "QodeAssist";
@ -106,7 +111,7 @@ void LLMClientInterface::sendData(const QByteArray &data)
m_performanceLogger.startTimeMeasurement(requestId); m_performanceLogger.startTimeMeasurement(requestId);
handleCompletion(request); handleCompletion(request);
} else if (method == "$/cancelRequest") { } else if (method == "$/cancelRequest") {
handleCancelRequest(request); handleCancelRequest();
} else if (method == "exit") { } else if (method == "exit") {
// TODO make exit handler // TODO make exit handler
} else { } else {
@ -114,8 +119,19 @@ void LLMClientInterface::sendData(const QByteArray &data)
} }
} }
void LLMClientInterface::handleCancelRequest(const QJsonObject &request) void LLMClientInterface::handleCancelRequest()
{ {
QSet<LLMCore::Provider *> providers;
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
if (it.value().provider) {
providers.insert(it.value().provider);
}
}
for (auto *provider : providers) {
disconnect(provider, nullptr, this, nullptr);
}
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
const RequestContext &ctx = it.value(); const RequestContext &ctx = it.value();
if (ctx.provider) { if (ctx.provider) {

View File

@ -49,6 +49,7 @@ public:
LLMCore::IPromptProvider *promptProvider, LLMCore::IPromptProvider *promptProvider,
Context::IDocumentReader &documentReader, Context::IDocumentReader &documentReader,
IRequestPerformanceLogger &performanceLogger); IRequestPerformanceLogger &performanceLogger);
~LLMClientInterface() override;
Utils::FilePath serverDeviceTemplate() const override; Utils::FilePath serverDeviceTemplate() const override;
@ -75,7 +76,7 @@ private:
void handleTextDocumentDidOpen(const QJsonObject &request); void handleTextDocumentDidOpen(const QJsonObject &request);
void handleInitialized(const QJsonObject &request); void handleInitialized(const QJsonObject &request);
void handleExit(const QJsonObject &request); void handleExit(const QJsonObject &request);
void handleCancelRequest(const QJsonObject &request); void handleCancelRequest();
struct RequestContext struct RequestContext
{ {

View File

@ -60,18 +60,23 @@ void HttpClient::onSendRequest(const HttpRequest &request)
void HttpClient::onReadyRead() void HttpClient::onReadyRead()
{ {
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender()); QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
if (!reply) if (!reply || reply->isFinished())
return; return;
QString requestId; QString requestId;
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
bool found = false;
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
if (it.value() == reply) { if (it.value() == reply) {
requestId = it.key(); requestId = it.key();
found = true;
break; break;
} }
} }
if (!found)
return;
} }
if (requestId.isEmpty()) if (requestId.isEmpty())
@ -89,19 +94,28 @@ void HttpClient::onFinished()
if (!reply) if (!reply)
return; return;
reply->disconnect();
QString requestId; QString requestId;
bool hasError = false; bool hasError = false;
QString errorMsg; QString errorMsg;
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
bool found = false;
for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) {
if (it.value() == reply) { if (it.value() == reply) {
requestId = it.key(); requestId = it.key();
m_activeRequests.erase(it); m_activeRequests.erase(it);
found = true;
break; break;
} }
} }
if (!found) {
reply->deleteLater();
return;
}
if (reply->error() != QNetworkReply::NoError) { if (reply->error() != QNetworkReply::NoError) {
hasError = true; hasError = true;
errorMsg = reply->errorString(); errorMsg = reply->errorString();