Fix session and agent rename handling

This commit is contained in:
Levi Neely 2026-08-02 22:34:39 +02:00
parent bd78b2b703
commit 220adf9b05
2 changed files with 45 additions and 13 deletions

View File

@ -378,10 +378,19 @@ bool Ollie9pClient::renameSession(const QString &sessionId, const QString &newNa
return false;
}
// Session names are mutable display names, not directory IDs. Writing the
// name file also avoids relying on Twstat, which is not implemented by all
// 9P frontends.
QProcess proc;
proc.setProgram(bin);
proc.setArguments({"-a", serverAddr(), "mv", "session/" + sessionId, "session/" + newName});
proc.setArguments({"-a", serverAddr(), "write", "session/" + sessionId + "/name"});
proc.start();
if (!proc.waitForStarted(3000)) {
qDebug() << "renameSession failed to start:" << proc.errorString();
return false;
}
proc.write((newName + "\n").toUtf8());
proc.closeWriteChannel();
proc.waitForFinished(5000);
if (proc.exitCode() != 0) {
@ -389,10 +398,19 @@ bool Ollie9pClient::renameSession(const QString &sessionId, const QString &newNa
return false;
}
// Update active session ID if we renamed the active session
if (m_activeSessionId == sessionId) {
// Stop path-based streams before changing the namespace entry. Otherwise
// Guarded streams can observe the old path disappearing and repeatedly
// restart against it while this synchronous write is in progress.
const bool active = m_activeSessionId == sessionId;
const QString activeAgent = m_agentId;
if (active)
stopAgentStreams();
if (active) {
m_activeSessionId = newName;
emit activeSessionIdChanged();
if (!activeAgent.isEmpty())
switchAgent(newName, activeAgent);
}
refreshSessions();
@ -409,15 +427,23 @@ bool Ollie9pClient::renameAgent(const QString &sessionId, const QString &agentId
return false;
}
// Write name=<newName> to the agent's ctl file — Plan 9 style.
// Agent names are mutable display names. Write the name file directly;
// ctl accepts commands, not name assignments, and the agent directory is
// keyed by its current display name.
const bool active = m_activeSessionId == sessionId && m_agentId == agentId;
if (active)
stopAgentStreams();
QProcess proc;
proc.setProgram(bin);
proc.setArguments({"-a", serverAddr(), "rdwr",
"session/" + sessionId + "/agent/" + agentId + "/ctl"});
proc.setArguments({"-a", serverAddr(), "write",
"session/" + sessionId + "/agent/" + agentId + "/name"});
proc.start();
proc.waitForStarted(3000);
QByteArray input = QString("name=" + newName + "\n").toUtf8();
proc.write(input);
if (!proc.waitForStarted(3000)) {
qDebug() << "renameAgent failed to start:" << proc.errorString();
return false;
}
proc.write((newName + "\n").toUtf8());
proc.closeWriteChannel();
proc.waitForFinished(5000);
@ -426,9 +452,9 @@ bool Ollie9pClient::renameAgent(const QString &sessionId, const QString &agentId
return false;
}
if (m_activeSessionId == sessionId) {
m_agentId = newName;
emit activeAgentIdChanged();
if (active) {
// switchAgent updates the active ID and restarts the path-based streams.
switchAgent(sessionId, newName);
}
refreshSessions();
@ -465,10 +491,15 @@ void Ollie9pClient::ensureRootDataLoaded()
// --- Streaming ---
void Ollie9pClient::stopStreams()
void Ollie9pClient::stopAgentStreams()
{
if (m_chat) m_chat->stop();
if (m_state) m_state->stop();
}
void Ollie9pClient::stopStreams()
{
stopAgentStreams();
if (m_event) m_event->stop();
}

View File

@ -85,6 +85,7 @@ signals:
void currentBackendChanged();
private:
void stopAgentStreams();
void stopStreams();
QString agentPath() const;
QByteArray run9p(const QStringList &args);