kate: add connection state tracking and auto-recovery
Adds a heartbeat timer (5s interval) that pings the 9P server with a cheap read. If the server goes down, the status bar turns red showing 'disconnected'. When it comes back, the plugin reconnects and re-selects the agent for the current project. Status bar now shows connection state: - Red '✗ disconnected' — server unreachable - Gray '○ no agent' — connected but no agent selected - Green '● kate/ID' — connected with active agent
This commit is contained in:
parent
0ff1025bb9
commit
2a6441cd53
|
|
@ -60,12 +60,19 @@ OllieKateView::OllieKateView(OllieKatePlugin *plugin, KTextEditor::MainWindow *m
|
|||
, m_plugin(plugin)
|
||||
, m_mainWindow(mainWindow)
|
||||
, m_9p(new Lib9pClient(this))
|
||||
, m_heartbeatTimer(new QTimer(this))
|
||||
{
|
||||
// Connect to 9P server
|
||||
if (!m_9p->connectDefault()) {
|
||||
m_connected = m_9p->connectDefault();
|
||||
if (!m_connected) {
|
||||
qWarning() << "Ollie: failed to connect to 9P server:" << m_9p->lastError();
|
||||
}
|
||||
|
||||
// Heartbeat timer — detect server death and reconnect
|
||||
m_heartbeatTimer->setInterval(5000);
|
||||
connect(m_heartbeatTimer, &QTimer::timeout, this, &OllieKateView::heartbeat);
|
||||
m_heartbeatTimer->start();
|
||||
|
||||
// Status bar indicator
|
||||
if (auto *win = qobject_cast<QMainWindow *>(m_mainWindow->window())) {
|
||||
m_statusLabel = new QLabel();
|
||||
|
|
@ -120,6 +127,7 @@ OllieKateView::OllieKateView(OllieKatePlugin *plugin, KTextEditor::MainWindow *m
|
|||
|
||||
OllieKateView::~OllieKateView()
|
||||
{
|
||||
m_heartbeatTimer->stop();
|
||||
delete m_ghost;
|
||||
if (m_statusLabel) {
|
||||
delete m_statusLabel;
|
||||
|
|
@ -229,10 +237,46 @@ QString OllieKateView::agentPath() const
|
|||
void OllieKateView::updateStatusLabel()
|
||||
{
|
||||
if (!m_statusLabel) return;
|
||||
if (m_agentId.isEmpty()) {
|
||||
if (!m_connected) {
|
||||
m_statusLabel->setText(QStringLiteral("✗ ollie: disconnected"));
|
||||
m_statusLabel->setStyleSheet(QStringLiteral("color: red; padding: 0px 4px;"));
|
||||
} else if (m_agentId.isEmpty()) {
|
||||
m_statusLabel->setText(QStringLiteral("○ ollie: no agent"));
|
||||
m_statusLabel->setStyleSheet(QStringLiteral("color: gray; padding: 0px 4px;"));
|
||||
} else {
|
||||
m_statusLabel->setText(QStringLiteral("● ollie: kate/") + m_agentId);
|
||||
m_statusLabel->setStyleSheet(QStringLiteral("color: green; padding: 0px 4px;"));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Connection Recovery ---
|
||||
|
||||
void OllieKateView::heartbeat()
|
||||
{
|
||||
// Try a cheap read to verify daemon is alive
|
||||
if (!m_9p->isConnected()) {
|
||||
if (!m_9p->connectDefault()) {
|
||||
if (m_connected) {
|
||||
m_connected = false;
|
||||
updateStatusLabel();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray result = m_9p->read(QStringLiteral("help"));
|
||||
bool alive = !result.isEmpty();
|
||||
|
||||
if (alive && !m_connected) {
|
||||
// Recovered — re-establish state
|
||||
m_connected = true;
|
||||
selectAgentForProject();
|
||||
updateStatusLabel();
|
||||
} else if (!alive && m_connected) {
|
||||
// Lost connection
|
||||
m_connected = false;
|
||||
m_9p->disconnect();
|
||||
updateStatusLabel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <QLabel>
|
||||
#include <QAction>
|
||||
#include <QEvent>
|
||||
#include <QTimer>
|
||||
|
||||
#include "lib9pclient.h"
|
||||
|
||||
|
|
@ -60,6 +61,7 @@ protected:
|
|||
|
||||
private slots:
|
||||
void onProjectChanged();
|
||||
void heartbeat();
|
||||
|
||||
private:
|
||||
// Actions
|
||||
|
|
@ -89,7 +91,9 @@ private:
|
|||
|
||||
QString m_sessionId;
|
||||
QString m_agentId;
|
||||
bool m_connected = false;
|
||||
|
||||
QTimer *m_heartbeatTimer;
|
||||
QLabel *m_statusLabel = nullptr;
|
||||
QPointer<OllieGhostProvider> m_ghost;
|
||||
bool m_ghostPrefix = false;
|
||||
|
|
|
|||
Reference in New Issue