gui: remove dead code (ninepconnection, streamfsm)
These were replaced by NativeStreamer which uses ollie-9p subprocess for streaming reads.
This commit is contained in:
parent
6fda37ae96
commit
e10912de08
|
|
@ -1,191 +0,0 @@
|
|||
#include "ninepconnection.h"
|
||||
|
||||
/*
|
||||
* TRANSITION TABLE
|
||||
* ================
|
||||
*
|
||||
* State | Event | Guard | Next State | Actions
|
||||
* -------------|--------------|------------------------|--------------|------------------
|
||||
* Disconnected | EvStart | | Connecting | spawnProcess
|
||||
* Connecting | EvOpenMarker | | Connected | emit connected
|
||||
* Connecting | EvExitFail | canRetry | RetryWait | scheduleRetry
|
||||
* Connecting | EvExitFail | !canRetry | Disconnected |
|
||||
* Connected | EvExitOk | | Connected | scheduleRetry (silent)
|
||||
* Connected | EvExitFail | canRetry | RetryWait | emit disconnected, scheduleRetry
|
||||
* Connected | EvExitFail | !canRetry | Disconnected | emit disconnected
|
||||
* RetryWait | EvRetryTimer | | Connecting | spawnProcess
|
||||
* Any | EvStop | | Disconnected | killProcess, emit disconnected (if was Connected)
|
||||
*
|
||||
* Signals:
|
||||
* - connected: emitted when entering Connected from any other state
|
||||
* - disconnected: emitted when leaving Connected for any other state
|
||||
*/
|
||||
|
||||
NinePConnection::NinePConnection(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_retryTimer.setSingleShot(true);
|
||||
connect(&m_retryTimer, &QTimer::timeout, this, [this]() { dispatch(EvRetryTimer); });
|
||||
}
|
||||
|
||||
NinePConnection::~NinePConnection()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void NinePConnection::start(const QString &program, const QStringList &args, int retryMs, int maxRetries)
|
||||
{
|
||||
m_program = program;
|
||||
m_args = args;
|
||||
m_retryMs = retryMs;
|
||||
m_maxRetries = maxRetries;
|
||||
m_retryCount = 0;
|
||||
dispatch(EvStart);
|
||||
}
|
||||
|
||||
void NinePConnection::stop()
|
||||
{
|
||||
dispatch(EvStop);
|
||||
}
|
||||
|
||||
void NinePConnection::dispatch(Event ev)
|
||||
{
|
||||
State next = m_state;
|
||||
|
||||
switch (m_state) {
|
||||
case Disconnected:
|
||||
if (ev == EvStart) {
|
||||
next = Connecting;
|
||||
spawnProcess();
|
||||
}
|
||||
break;
|
||||
|
||||
case Connecting:
|
||||
if (ev == EvStop) {
|
||||
next = Disconnected;
|
||||
killProcess();
|
||||
} else if (ev == EvOpenMarker) {
|
||||
next = Connected;
|
||||
} else if (ev == EvExitFail) {
|
||||
bool canRetry = m_retryMs > 0 && (m_maxRetries == 0 || m_retryCount < m_maxRetries);
|
||||
if (canRetry) {
|
||||
next = RetryWait;
|
||||
++m_retryCount;
|
||||
scheduleRetry();
|
||||
} else {
|
||||
next = Disconnected;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Connected:
|
||||
if (ev == EvStop) {
|
||||
next = Disconnected;
|
||||
killProcess();
|
||||
} else if (ev == EvExitOk) {
|
||||
// Silent restart - stay Connected
|
||||
m_retryCount = 0;
|
||||
scheduleRetry();
|
||||
} else if (ev == EvExitFail) {
|
||||
bool canRetry = m_retryMs > 0 && (m_maxRetries == 0 || m_retryCount < m_maxRetries);
|
||||
if (canRetry) {
|
||||
next = RetryWait;
|
||||
++m_retryCount;
|
||||
scheduleRetry();
|
||||
} else {
|
||||
next = Disconnected;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RetryWait:
|
||||
if (ev == EvStop) {
|
||||
next = Disconnected;
|
||||
m_retryTimer.stop();
|
||||
} else if (ev == EvRetryTimer) {
|
||||
next = Connecting;
|
||||
spawnProcess();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (next != m_state)
|
||||
enter(next);
|
||||
}
|
||||
|
||||
void NinePConnection::enter(State state)
|
||||
{
|
||||
State prev = m_state;
|
||||
m_state = state;
|
||||
emit stateChanged(state);
|
||||
|
||||
if (state == Connected && prev != Connected)
|
||||
emit connected();
|
||||
else if (prev == Connected && state != Connected)
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
void NinePConnection::spawnProcess()
|
||||
{
|
||||
if (m_process) return;
|
||||
m_stderr.clear();
|
||||
m_openMarkerSeen = false;
|
||||
m_process = new QProcess(this);
|
||||
connect(m_process, &QProcess::readyReadStandardOutput, this, &NinePConnection::onStdout);
|
||||
connect(m_process, &QProcess::readyReadStandardError, this, &NinePConnection::onStderr);
|
||||
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, &NinePConnection::onFinished);
|
||||
m_process->start(m_program, m_args);
|
||||
}
|
||||
|
||||
void NinePConnection::killProcess()
|
||||
{
|
||||
m_retryTimer.stop();
|
||||
if (m_process) {
|
||||
m_process->disconnect(this);
|
||||
m_process->kill();
|
||||
m_process->waitForFinished(1000);
|
||||
m_process->deleteLater();
|
||||
m_process = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void NinePConnection::scheduleRetry()
|
||||
{
|
||||
if (m_retryMs > 0)
|
||||
m_retryTimer.start(m_retryMs);
|
||||
else
|
||||
spawnProcess();
|
||||
}
|
||||
|
||||
void NinePConnection::onStdout()
|
||||
{
|
||||
const QByteArray data = m_process->readAllStandardOutput();
|
||||
if (!data.isEmpty())
|
||||
emit readyRead(data);
|
||||
}
|
||||
|
||||
void NinePConnection::onStderr()
|
||||
{
|
||||
m_stderr += m_process->readAllStandardError();
|
||||
while (true) {
|
||||
int end = m_stderr.indexOf('\n');
|
||||
if (end < 0) break;
|
||||
QByteArray line = m_stderr.left(end).trimmed();
|
||||
m_stderr.remove(0, end + 1);
|
||||
if (line == "OLLIE_9P_OPEN") {
|
||||
m_openMarkerSeen = true;
|
||||
dispatch(EvOpenMarker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NinePConnection::onFinished(int exitCode, QProcess::ExitStatus)
|
||||
{
|
||||
if (!m_process) return;
|
||||
m_process->deleteLater();
|
||||
m_process = nullptr;
|
||||
|
||||
bool success = (exitCode == 0 && m_openMarkerSeen);
|
||||
dispatch(success ? EvExitOk : EvExitFail);
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
#ifndef NINEPCONNECTION_H
|
||||
#define NINEPCONNECTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
|
||||
/**
|
||||
* NinePConnection - Resilient 9P subprocess connection.
|
||||
*
|
||||
* State machine with explicit events and transition table.
|
||||
*/
|
||||
class NinePConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State { Disconnected, Connecting, Connected, RetryWait };
|
||||
Q_ENUM(State)
|
||||
|
||||
enum Event { EvStart, EvStop, EvOpenMarker, EvExitOk, EvExitFail, EvRetryTimer };
|
||||
Q_ENUM(Event)
|
||||
|
||||
explicit NinePConnection(QObject *parent = nullptr);
|
||||
~NinePConnection() override;
|
||||
|
||||
void start(const QString &program, const QStringList &args, int retryMs = 4000, int maxRetries = 0);
|
||||
void stop();
|
||||
State state() const { return m_state; }
|
||||
|
||||
signals:
|
||||
void connected();
|
||||
void disconnected();
|
||||
void readyRead(const QByteArray &data);
|
||||
void stateChanged(State state);
|
||||
|
||||
private slots:
|
||||
void onStdout();
|
||||
void onStderr();
|
||||
void onFinished(int exitCode, QProcess::ExitStatus status);
|
||||
|
||||
private:
|
||||
void dispatch(Event ev);
|
||||
void enter(State state);
|
||||
void spawnProcess();
|
||||
void killProcess();
|
||||
void scheduleRetry();
|
||||
|
||||
QProcess *m_process = nullptr;
|
||||
QTimer m_retryTimer;
|
||||
QString m_program;
|
||||
QStringList m_args;
|
||||
QByteArray m_stderr;
|
||||
State m_state = Disconnected;
|
||||
int m_retryMs = 4000;
|
||||
int m_maxRetries = 0;
|
||||
int m_retryCount = 0;
|
||||
bool m_openMarkerSeen = false;
|
||||
};
|
||||
|
||||
#endif // NINEPCONNECTION_H
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
#include "streamfsm.h"
|
||||
|
||||
StreamFsm::StreamFsm(RestartPolicy policy, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_policy(policy)
|
||||
{
|
||||
}
|
||||
|
||||
StreamFsm::~StreamFsm()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void StreamFsm::start(const QString &program, const QStringList &args)
|
||||
{
|
||||
m_program = program;
|
||||
m_args = args;
|
||||
if (m_state == Idle)
|
||||
startProcess();
|
||||
}
|
||||
|
||||
void StreamFsm::stop()
|
||||
{
|
||||
if (m_state == Idle)
|
||||
return;
|
||||
|
||||
if (m_proc) {
|
||||
// Disconnect before killing so onFinished doesn't fire during teardown.
|
||||
m_proc->disconnect();
|
||||
m_proc->kill();
|
||||
m_proc->waitForFinished(1000);
|
||||
m_proc->deleteLater();
|
||||
m_proc = nullptr;
|
||||
}
|
||||
transitTo(Idle);
|
||||
}
|
||||
|
||||
void StreamFsm::setGuard(std::function<bool()> guard)
|
||||
{
|
||||
m_guard = std::move(guard);
|
||||
}
|
||||
|
||||
void StreamFsm::startProcess()
|
||||
{
|
||||
if (m_state != Idle)
|
||||
return;
|
||||
|
||||
m_proc = new QProcess(this);
|
||||
connect(m_proc, &QProcess::readyReadStandardOutput,
|
||||
this, &StreamFsm::onReadyRead);
|
||||
connect(m_proc,
|
||||
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
||||
this, &StreamFsm::onFinished);
|
||||
m_proc->start(m_program, m_args);
|
||||
transitTo(Running);
|
||||
}
|
||||
|
||||
void StreamFsm::onReadyRead()
|
||||
{
|
||||
QByteArray data = m_proc->readAllStandardOutput();
|
||||
if (!data.isEmpty())
|
||||
emit readyRead(data);
|
||||
}
|
||||
|
||||
void StreamFsm::onFinished(int, QProcess::ExitStatus)
|
||||
{
|
||||
// Clean up the finished process.
|
||||
m_proc->deleteLater();
|
||||
m_proc = nullptr;
|
||||
transitTo(Idle);
|
||||
|
||||
// Decide what to do next based on policy.
|
||||
switch (m_policy) {
|
||||
case Oneshot:
|
||||
emit died();
|
||||
break;
|
||||
case Looping:
|
||||
startProcess();
|
||||
break;
|
||||
case Guarded:
|
||||
if (m_guard && m_guard())
|
||||
startProcess();
|
||||
else
|
||||
emit died();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamFsm::transitTo(State s)
|
||||
{
|
||||
m_state = s;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#ifndef STREAMFSM_H
|
||||
#define STREAMFSM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <functional>
|
||||
|
||||
/// A formal 2-state FSM wrapping a QProcess streaming lifecycle.
|
||||
///
|
||||
/// States: Idle ──start()──→ Running ──stop()──→ Idle
|
||||
/// Running ──process exit──→ Idle ──[policy]──→ Running | emit died()
|
||||
///
|
||||
/// Three restart policies:
|
||||
/// Oneshot — process runs once, then emits died()
|
||||
/// Looping — process always restarts after exit
|
||||
/// Guarded — process restarts only if guard() returns true
|
||||
///
|
||||
/// All signal connections are managed internally. stop() is safe to call
|
||||
/// from any state; it disconnects before killing to prevent spurious signals.
|
||||
class StreamFsm : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State { Idle, Running };
|
||||
enum RestartPolicy { Oneshot, Looping, Guarded };
|
||||
|
||||
explicit StreamFsm(RestartPolicy policy, QObject *parent = nullptr);
|
||||
~StreamFsm();
|
||||
|
||||
State state() const { return m_state; }
|
||||
RestartPolicy policy() const { return m_policy; }
|
||||
|
||||
/// Store program/args and start the process (no-op if already Running).
|
||||
void start(const QString &program, const QStringList &args);
|
||||
|
||||
/// Kill the process and transition to Idle. Does not emit died().
|
||||
void stop();
|
||||
|
||||
/// Guard predicate for Guarded policy — called after exit to decide
|
||||
/// whether to restart. Not used for Oneshot or Looping.
|
||||
void setGuard(std::function<bool()> guard);
|
||||
|
||||
signals:
|
||||
/// Emitted with data from the process's stdout (partial reads).
|
||||
void readyRead(const QByteArray &data);
|
||||
|
||||
/// Emitted when the process has exited and will NOT be restarted
|
||||
/// (Oneshot policy, or Guarded policy with a false guard).
|
||||
void died();
|
||||
|
||||
private slots:
|
||||
void onReadyRead();
|
||||
void onFinished(int exitCode, QProcess::ExitStatus status);
|
||||
|
||||
private:
|
||||
void startProcess();
|
||||
void transitTo(State s);
|
||||
|
||||
State m_state = Idle;
|
||||
QProcess *m_proc = nullptr;
|
||||
RestartPolicy m_policy;
|
||||
std::function<bool()> m_guard;
|
||||
QString m_program;
|
||||
QStringList m_args;
|
||||
};
|
||||
|
||||
#endif // STREAMFSM_H
|
||||
Reference in New Issue