LanguageClient: improve Server startup

Starting a client does not need to be done via
LanguageClientManager::startClient anymore but can be done via
Client::start()

Change-Id: I571e96b6ad7d64786a345edf5dbb38208b9a1d12
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-02-12 14:01:24 +01:00
parent 9bd8dc41d2
commit 166fce5036
4 changed files with 37 additions and 39 deletions

View File

@@ -861,9 +861,12 @@ QList<Diagnostic> Client::diagnosticsAt(const DocumentUri &uri, const QTextCurso
return m_diagnosticManager.diagnosticsAt(uri, cursor); return m_diagnosticManager.diagnosticsAt(uri, cursor);
} }
bool Client::start() void Client::start()
{ {
return m_clientInterface->start(); if (m_clientInterface->start())
LanguageClientManager::clientStarted(this);
else
LanguageClientManager::clientFinished(this);
} }
bool Client::reset() bool Client::reset()

View File

@@ -151,7 +151,7 @@ public:
const LanguageServerProtocol::DocumentUri &uri, const LanguageServerProtocol::DocumentUri &uri,
const QTextCursor &cursor) const; const QTextCursor &cursor) const;
bool start(); void start();
bool reset(); bool reset();
void log(const QString &message); void log(const QString &message);

View File

@@ -98,28 +98,46 @@ void LanguageClientManager::init()
managerInstance = new LanguageClientManager(LanguageClientPlugin::instance()); managerInstance = new LanguageClientManager(LanguageClientPlugin::instance());
} }
void LanguageClientManager::startClient(Client *client) void LanguageClientManager::clientStarted(Client *client)
{ {
QTC_ASSERT(managerInstance, return); QTC_ASSERT(managerInstance, return);
QTC_ASSERT(client, return); QTC_ASSERT(client, return);
if (managerInstance->m_shuttingDown) { if (managerInstance->m_shuttingDown) {
managerInstance->clientFinished(client); clientFinished(client);
return; return;
} }
if (!managerInstance->m_clients.contains(client))
managerInstance->m_clients.append(client);
connect(client, &Client::finished, managerInstance, [client](){ connect(client, &Client::finished, managerInstance, [client](){
managerInstance->clientFinished(client); clientFinished(client);
}); });
if (client->start())
client->initialize();
else
managerInstance->clientFinished(client);
connect(client, connect(client,
&Client::initialized, &Client::initialized,
&managerInstance->m_currentDocumentLocatorFilter, &managerInstance->m_currentDocumentLocatorFilter,
&DocumentLocatorFilter::updateCurrentClient); &DocumentLocatorFilter::updateCurrentClient);
client->initialize();
}
void LanguageClientManager::clientFinished(Client *client)
{
QTC_ASSERT(managerInstance, return);
constexpr int restartTimeoutS = 5;
const bool unexpectedFinish = client->state() != Client::Shutdown
&& client->state() != Client::ShutdownRequested;
if (unexpectedFinish && !managerInstance->m_shuttingDown && client->reset()) {
client->disconnect(managerInstance);
client->log(tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS));
QTimer::singleShot(restartTimeoutS * 1000, client, [client]() { client->start(); });
for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client))
client->deactivateDocument(document);
} else {
if (unexpectedFinish && !managerInstance->m_shuttingDown)
client->log(tr("Unexpectedly finished."));
for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client))
managerInstance->m_clientForDocument.remove(document);
deleteClient(client);
if (managerInstance->m_shuttingDown && managerInstance->m_clients.isEmpty())
emit managerInstance->shutdownFinished();
}
} }
Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplorer::Project *project) Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplorer::Project *project)
@@ -130,7 +148,7 @@ Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplore
Client *client = setting->createClient(); Client *client = setting->createClient();
QTC_ASSERT(client, return nullptr); QTC_ASSERT(client, return nullptr);
client->setCurrentProject(project); client->setCurrentProject(project);
startClient(client); client->start();
managerInstance->m_clientsForSetting[setting->m_id].append(client); managerInstance->m_clientsForSetting[setting->m_id].append(client);
return client; return client;
} }
@@ -380,28 +398,6 @@ QVector<Client *> LanguageClientManager::reachableClients()
return Utils::filtered(m_clients, &Client::reachable); return Utils::filtered(m_clients, &Client::reachable);
} }
void LanguageClientManager::clientFinished(Client *client)
{
constexpr int restartTimeoutS = 5;
const bool unexpectedFinish = client->state() != Client::Shutdown
&& client->state() != Client::ShutdownRequested;
if (unexpectedFinish && !m_shuttingDown && client->reset()) {
client->disconnect(this);
client->log(tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS));
QTimer::singleShot(restartTimeoutS * 1000, client, [client]() { startClient(client); });
for (TextEditor::TextDocument *document : m_clientForDocument.keys(client))
client->deactivateDocument(document);
} else {
if (unexpectedFinish && !m_shuttingDown)
client->log(tr("Unexpectedly finished."));
for (TextEditor::TextDocument *document : m_clientForDocument.keys(client))
m_clientForDocument.remove(document);
deleteClient(client);
if (m_shuttingDown && m_clients.isEmpty())
emit shutdownFinished();
}
}
void LanguageClientManager::editorOpened(Core::IEditor *editor) void LanguageClientManager::editorOpened(Core::IEditor *editor)
{ {
using namespace TextEditor; using namespace TextEditor;

View File

@@ -58,7 +58,8 @@ public:
static void init(); static void init();
static void startClient(Client *client); static void clientStarted(Client *client);
static void clientFinished(Client *client);
static Client *startClient(BaseSettings *setting, ProjectExplorer::Project *project = nullptr); static Client *startClient(BaseSettings *setting, ProjectExplorer::Project *project = nullptr);
static QVector<Client *> clients(); static QVector<Client *> clients();
@@ -114,8 +115,6 @@ private:
QVector<Client *> reachableClients(); QVector<Client *> reachableClients();
void clientFinished(Client *client);
bool m_shuttingDown = false; bool m_shuttingDown = false;
QVector<Client *> m_clients; QVector<Client *> m_clients;
QList<BaseSettings *> m_currentSettings; // owned QList<BaseSettings *> m_currentSettings; // owned