single-pass session parsing

Consolidate refreshSessions() to do everything in one iteration:
- Parse session/idx data
- Update m_agentConnected cache
- Track active session/agent existence
- Emit connection state change

Eliminates separate reconcileAgentConnections() call and second loop
to check active session/agent. O(n) instead of O(3n).
This commit is contained in:
Levi Neely 2026-08-03 20:16:07 +02:00
parent 57b3ce04e3
commit 249a19e261
1 changed files with 40 additions and 25 deletions

View File

@ -323,6 +323,13 @@ void Ollie9pClient::refreshSessions()
QString raw = QString::fromUtf8(out);
m_sessions.clear();
// Track if active session/agent still exist during parsing
bool activeSessionFound = false;
bool activeAgentFound = false;
bool activeAgentConnected = false;
bool activeAgentWasConnected = m_agentConnected.value(agentKey(m_activeSessionId, m_agentId), false);
if (!raw.isEmpty()) {
for (const QString &line : raw.split('\n', Qt::SkipEmptyParts)) {
QStringList parts = line.split('\t');
@ -330,11 +337,19 @@ void Ollie9pClient::refreshSessions()
// Where agents is semicolon-separated: name:id:state;name:id:state
if (parts.size() < 2) continue;
const QString sessionId = parts.value(1);
const bool isConnected = (parts.value(3) == "true");
const bool isActiveSession = (sessionId == m_activeSessionId);
if (isActiveSession) {
activeSessionFound = true;
}
QVariantMap session;
session["name"] = parts.value(0);
session["id"] = parts.value(1);
session["id"] = sessionId;
session["paused"] = (parts.value(2) == "true");
session["connected"] = (parts.value(3) == "true");
session["connected"] = isConnected;
session["cwd"] = parts.value(4);
session["backend"] = parts.value(5);
session["model"] = parts.value(6);
@ -346,12 +361,23 @@ void Ollie9pClient::refreshSessions()
for (const QString &agentEntry : agentStr.split(';', Qt::SkipEmptyParts)) {
QStringList agentParts = agentEntry.split(':');
if (agentParts.size() >= 3) {
const QString agentId = agentParts.value(1);
QVariantMap av;
av["name"] = agentParts.value(0);
av["id"] = agentParts.value(1);
av["id"] = agentId;
av["state"] = agentParts.value(2);
av["connected"] = session["connected"]; // Agent inherits session connectivity
av["connected"] = isConnected;
agents.append(av);
// Update agent connected cache inline
const QString key = agentKey(sessionId, agentId);
m_agentConnected[key] = isConnected;
// Check if this is the active agent
if (isActiveSession && agentId == m_agentId) {
activeAgentFound = true;
activeAgentConnected = isConnected;
}
}
}
}
@ -359,29 +385,18 @@ void Ollie9pClient::refreshSessions()
m_sessions.append(session);
}
}
reconcileAgentConnections();
// Handle active agent connection state change
if (activeAgentFound && !activeAgentWasConnected && activeAgentConnected) {
emit sessionConnected();
startActiveAgentStreams();
}
emit sessionsChanged();
// Check if the currently active session/agent still exist
// Handle active session/agent removal
if (!m_activeSessionId.isEmpty()) {
bool sessionFound = false;
bool agentFound = false;
for (const QVariant &v : std::as_const(m_sessions)) {
const QVariantMap session = v.toMap();
if (session.value("id").toString() == m_activeSessionId) {
sessionFound = true;
if (!m_agentId.isEmpty()) {
for (const QVariant &av : session.value("agents").toList()) {
if (av.toMap().value("id").toString() == m_agentId) {
agentFound = true;
break;
}
}
}
break;
}
}
if (!sessionFound) {
if (!activeSessionFound) {
// Session was killed — clear both and stop streams
stopStreams();
m_activeSessionId.clear();
@ -390,7 +405,7 @@ void Ollie9pClient::refreshSessions()
emit activeSessionIdChanged();
emit activeAgentIdChanged();
emit activeStateChanged();
} else if (!m_agentId.isEmpty() && !agentFound) {
} else if (!m_agentId.isEmpty() && !activeAgentFound) {
// Agent was killed but session still exists — clear agent only
stopStreams();
m_agentId.clear();