From e7110810f8109f6abe276d5171db689fe955e936 Mon Sep 17 00:00:00 2001 From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com> Date: Sat, 1 Nov 2025 20:51:01 +0100 Subject: [PATCH] fix: Clear connection before cancel --- ChatView/ClientInterface.cpp | 16 +++++++++++++++- LLMClientInterface.cpp | 20 ++++++++++++++++++-- LLMClientInterface.hpp | 3 ++- llmcore/HttpClient.cpp | 16 +++++++++++++++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/ChatView/ClientInterface.cpp b/ChatView/ClientInterface.cpp index 835ed5a..f87e911 100644 --- a/ChatView/ClientInterface.cpp +++ b/ChatView/ClientInterface.cpp @@ -52,7 +52,10 @@ ClientInterface::ClientInterface( , m_contextManager(new Context::ContextManager(this)) {} -ClientInterface::~ClientInterface() = default; +ClientInterface::~ClientInterface() +{ + cancelRequest(); +} void ClientInterface::sendMessage( const QString &message, @@ -201,6 +204,17 @@ void ClientInterface::clearMessages() void ClientInterface::cancelRequest() { + QSet 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) { const RequestContext &ctx = it.value(); if (ctx.provider) { diff --git a/LLMClientInterface.cpp b/LLMClientInterface.cpp index db233d6..ba81a29 100644 --- a/LLMClientInterface.cpp +++ b/LLMClientInterface.cpp @@ -51,6 +51,11 @@ LLMClientInterface::LLMClientInterface( { } +LLMClientInterface::~LLMClientInterface() +{ + handleCancelRequest(); +} + Utils::FilePath LLMClientInterface::serverDeviceTemplate() const { return "QodeAssist"; @@ -106,7 +111,7 @@ void LLMClientInterface::sendData(const QByteArray &data) m_performanceLogger.startTimeMeasurement(requestId); handleCompletion(request); } else if (method == "$/cancelRequest") { - handleCancelRequest(request); + handleCancelRequest(); } else if (method == "exit") { // TODO make exit handler } else { @@ -114,8 +119,19 @@ void LLMClientInterface::sendData(const QByteArray &data) } } -void LLMClientInterface::handleCancelRequest(const QJsonObject &request) +void LLMClientInterface::handleCancelRequest() { + QSet 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) { const RequestContext &ctx = it.value(); if (ctx.provider) { diff --git a/LLMClientInterface.hpp b/LLMClientInterface.hpp index 8e1911c..3f25e29 100644 --- a/LLMClientInterface.hpp +++ b/LLMClientInterface.hpp @@ -49,6 +49,7 @@ public: LLMCore::IPromptProvider *promptProvider, Context::IDocumentReader &documentReader, IRequestPerformanceLogger &performanceLogger); + ~LLMClientInterface() override; Utils::FilePath serverDeviceTemplate() const override; @@ -75,7 +76,7 @@ private: void handleTextDocumentDidOpen(const QJsonObject &request); void handleInitialized(const QJsonObject &request); void handleExit(const QJsonObject &request); - void handleCancelRequest(const QJsonObject &request); + void handleCancelRequest(); struct RequestContext { diff --git a/llmcore/HttpClient.cpp b/llmcore/HttpClient.cpp index a32de76..d2f3d27 100644 --- a/llmcore/HttpClient.cpp +++ b/llmcore/HttpClient.cpp @@ -60,18 +60,23 @@ void HttpClient::onSendRequest(const HttpRequest &request) void HttpClient::onReadyRead() { QNetworkReply *reply = qobject_cast(sender()); - if (!reply) + if (!reply || reply->isFinished()) return; QString requestId; { QMutexLocker locker(&m_mutex); + bool found = false; for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { if (it.value() == reply) { requestId = it.key(); + found = true; break; } } + + if (!found) + return; } if (requestId.isEmpty()) @@ -89,19 +94,28 @@ void HttpClient::onFinished() if (!reply) return; + reply->disconnect(); + QString requestId; bool hasError = false; QString errorMsg; { QMutexLocker locker(&m_mutex); + bool found = false; for (auto it = m_activeRequests.begin(); it != m_activeRequests.end(); ++it) { if (it.value() == reply) { requestId = it.key(); m_activeRequests.erase(it); + found = true; break; } } + if (!found) { + reply->deleteLater(); + return; + } + if (reply->error() != QNetworkReply::NoError) { hasError = true; errorMsg = reply->errorString();