forked from Public/monero-gui
Merge pull request #217
3752ec7send page: check daemon status after every refresh (Jaquee)01549a3walletManager: coding conventions (Jaquee)0ae3d67daemon console -> log + adjusted height (Jaquee)0e8cd14Wallet: add m_initialized (Jaquee)c7232e1set wallet connection status before querying sync status (Jaquee)3f8e05dWallet: Cache connection status query (Jaquee)36a6b89connect onWalletConnectionStatusChanged() (Jaquee)93a8200Transfer: new connectionStatus handling + show status msg (Jaquee)76e6ae8remove reference to old pw-dialog (Jaquee)18b7a67Wallet: add connectionStatusChanged signal (Jaquee)d9f4ab4daemonManager: wait for daemon stop on app close (Jaquee)f62bb68daemonManagerDialog: use new ConnectionStatus enum (Jaquee)dd01f59hide daemon sync progress after disconnecting wallet (Jaquee)8d19a03DaemonManager: add stateChanged() (Jaquee)760e01bdaemonManagerDialog: show processdialog when starting (Jaquee)bb881d9show processingSplash when starting/stopping daemon (Jaquee)8361ddaresolve rebase conflict (Jaquee)8dfa79eShutdown daemon and close wallet properly on app exit (Jaquee)7876957DaemonManager::closing() (Jacob Brydolf)065b060main: debug messages (Jacob Brydolf)b4eb489DaemonManager: forward command line arguments to monerod (Jacob Brydolf)752ff26forward command line arguments to DaemonManager (Jaquee)7840dabDaemonManager: console debug output (Jacob Brydolf)14a5bd5settings: added daemon console (Jacob Brydolf)b53ef00history tx details: resized popup (Jacob Brydolf)b4f29b2StandardDialog: changed default sizes (Jacob Brydolf)5855700daemonManagerDialog: added starting signal (Jacob Brydolf)3a43154DaemonManager: added console updated signals (Jacob Brydolf)3df9e44DaemonManager: windows support (Jacob Brydolf)5da9f8fstandardDialog: close window before continue (Jacob Brydolf)5a110f4replace message dialog with custom dialog (Jacob Brydolf)d465780resized standard dialog (Jacob Brydolf)482bd30settings: enable/disable daemon start/stop buttons (Jacob Brydolf)4e7de8cproper daemon shutdown on app exit (Jaquee)48471f3onDaemonStarted/stopped signals/slots (Jaquee)de635cbpw dialog: close popup before continue (Jacob Brydolf)86772beadded standardDialog component (Jacob Brydolf)ae977afsettings: add daemon manager (Jacob Brydolf)2775124small error in daemon manager dialog (Jacob Brydolf)82c39e0WalletManager: include dependencies (Jaquee)1c6884eShow daemon manager dialog if daemon isnt started (Jacob Brydolf)9fbfbc4daemonManager: embed as context property (Jaquee)4cdc258WalletManager: basic functionality (Jacob Brydolf)
This commit is contained in:
142
src/daemon/DaemonManager.cpp
Normal file
142
src/daemon/DaemonManager.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "DaemonManager.h"
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QApplication>
|
||||
#include <QProcess>
|
||||
|
||||
DaemonManager * DaemonManager::m_instance = nullptr;
|
||||
QStringList DaemonManager::m_clArgs;
|
||||
|
||||
DaemonManager *DaemonManager::instance(const QStringList *args)
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new DaemonManager;
|
||||
// store command line arguments for later use
|
||||
m_clArgs = *args;
|
||||
m_clArgs.removeFirst();
|
||||
}
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
bool DaemonManager::start()
|
||||
{
|
||||
//
|
||||
QString process;
|
||||
#ifdef Q_OS_WIN
|
||||
process = QApplication::applicationDirPath() + "/monerod.exe";
|
||||
#elif defined(Q_OS_UNIX)
|
||||
process = QApplication::applicationDirPath() + "/monerod";
|
||||
#endif
|
||||
|
||||
if (process.length() == 0) {
|
||||
qDebug() << "no daemon binary defined for current platform";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// prepare command line arguments and pass to monerod
|
||||
QStringList arguments;
|
||||
foreach (const QString &str, m_clArgs) {
|
||||
qDebug() << QString(" [%1] ").arg(str);
|
||||
arguments << str;
|
||||
}
|
||||
|
||||
qDebug() << "starting monerod " + process;
|
||||
qDebug() << "With command line arguments " << arguments;
|
||||
|
||||
m_daemon = new QProcess();
|
||||
initialized = true;
|
||||
|
||||
// Connect output slots
|
||||
connect (m_daemon, SIGNAL(readyReadStandardOutput()), this, SLOT(printOutput()));
|
||||
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError()));
|
||||
|
||||
// Start monerod
|
||||
m_daemon->start(process,arguments);
|
||||
bool started = m_daemon->waitForStarted();
|
||||
|
||||
// add state changed listener
|
||||
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState)));
|
||||
|
||||
if (!started) {
|
||||
qDebug() << "Daemon start error: " + m_daemon->errorString();
|
||||
} else {
|
||||
emit daemonStarted();
|
||||
}
|
||||
|
||||
return started;
|
||||
}
|
||||
|
||||
bool DaemonManager::stop()
|
||||
{
|
||||
if (initialized) {
|
||||
qDebug() << "stopping daemon";
|
||||
// we can't use QProcess::terminate() on windows console process
|
||||
// write exit command to stdin
|
||||
m_daemon->write("exit\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DaemonManager::stateChanged(QProcess::ProcessState state)
|
||||
{
|
||||
qDebug() << "STATE CHANGED: " << state;
|
||||
if (state == QProcess::NotRunning) {
|
||||
emit daemonStopped();
|
||||
}
|
||||
}
|
||||
|
||||
void DaemonManager::printOutput()
|
||||
{
|
||||
QByteArray byteArray = m_daemon->readAllStandardOutput();
|
||||
QStringList strLines = QString(byteArray).split("\n");
|
||||
|
||||
foreach (QString line, strLines) {
|
||||
emit daemonConsoleUpdated(line);
|
||||
qDebug() << "Daemon: " + line;
|
||||
}
|
||||
}
|
||||
|
||||
void DaemonManager::printError()
|
||||
{
|
||||
QByteArray byteArray = m_daemon->readAllStandardError();
|
||||
QStringList strLines = QString(byteArray).split("\n");
|
||||
|
||||
foreach (QString line, strLines) {
|
||||
emit daemonConsoleUpdated(line);
|
||||
qDebug() << "Daemon ERROR: " + line;
|
||||
}
|
||||
}
|
||||
|
||||
bool DaemonManager::running() const
|
||||
{
|
||||
if (initialized) {
|
||||
qDebug() << m_daemon->state();
|
||||
qDebug() << QProcess::NotRunning;
|
||||
// m_daemon->write("status\n");
|
||||
return m_daemon->state() > QProcess::NotRunning;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DaemonManager::DaemonManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DaemonManager::closing()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
stop();
|
||||
// Wait for daemon to stop before exiting (max 10 secs)
|
||||
if (initialized) {
|
||||
m_daemon->waitForFinished(10000);
|
||||
}
|
||||
}
|
||||
43
src/daemon/DaemonManager.h
Normal file
43
src/daemon/DaemonManager.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef DAEMONMANAGER_H
|
||||
#define DAEMONMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QProcess>
|
||||
|
||||
class DaemonManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
static DaemonManager * instance(const QStringList *args);
|
||||
|
||||
Q_INVOKABLE bool start();
|
||||
Q_INVOKABLE bool stop();
|
||||
|
||||
// return true if daemon process is started
|
||||
Q_INVOKABLE bool running() const;
|
||||
|
||||
signals:
|
||||
void daemonStarted();
|
||||
void daemonStopped();
|
||||
void daemonConsoleUpdated(QString message);
|
||||
|
||||
public slots:
|
||||
void printOutput();
|
||||
void printError();
|
||||
void closing();
|
||||
void stateChanged(QProcess::ProcessState state);
|
||||
|
||||
private:
|
||||
|
||||
explicit DaemonManager(QObject *parent = 0);
|
||||
static DaemonManager * m_instance;
|
||||
static QStringList m_clArgs;
|
||||
QProcess *m_daemon;
|
||||
bool initialized = false;
|
||||
|
||||
};
|
||||
|
||||
#endif // DAEMONMANAGER_H
|
||||
@@ -15,6 +15,7 @@
|
||||
namespace {
|
||||
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10;
|
||||
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 60;
|
||||
static const int WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS = 5;
|
||||
}
|
||||
|
||||
class WalletListenerImpl : public Bitmonero::WalletListener
|
||||
@@ -89,7 +90,18 @@ Wallet::Status Wallet::status() const
|
||||
|
||||
Wallet::ConnectionStatus Wallet::connected() const
|
||||
{
|
||||
return static_cast<ConnectionStatus>(m_walletImpl->connected());
|
||||
// cache connection status
|
||||
if (!m_initialized || m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl) {
|
||||
m_initialized = true;
|
||||
ConnectionStatus newStatus = static_cast<ConnectionStatus>(m_walletImpl->connected());
|
||||
if (newStatus != m_connectionStatus) {
|
||||
m_connectionStatus = newStatus;
|
||||
emit connectionStatusChanged();
|
||||
}
|
||||
m_connectionStatusTime.restart();
|
||||
}
|
||||
|
||||
return m_connectionStatus;
|
||||
}
|
||||
|
||||
bool Wallet::synchronized() const
|
||||
@@ -424,9 +436,16 @@ Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent)
|
||||
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
|
||||
, m_daemonBlockChainTargetHeight(0)
|
||||
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
|
||||
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
||||
{
|
||||
m_history = new TransactionHistory(m_walletImpl->history(), this);
|
||||
m_walletImpl->setListener(new WalletListenerImpl(this));
|
||||
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
|
||||
// start cache timers
|
||||
m_connectionStatusTime.restart();
|
||||
m_daemonBlockChainHeightTime.restart();
|
||||
m_daemonBlockChainTargetHeightTime.restart();
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
Wallet::~Wallet()
|
||||
|
||||
@@ -200,6 +200,8 @@ signals:
|
||||
// emitted when transaction is created async
|
||||
void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount);
|
||||
|
||||
void connectionStatusChanged() const;
|
||||
|
||||
private:
|
||||
Wallet(QObject * parent = nullptr);
|
||||
Wallet(Bitmonero::Wallet *w, QObject * parent = 0);
|
||||
@@ -221,6 +223,10 @@ private:
|
||||
mutable QTime m_daemonBlockChainTargetHeightTime;
|
||||
mutable quint64 m_daemonBlockChainTargetHeight;
|
||||
int m_daemonBlockChainTargetHeightTtl;
|
||||
mutable ConnectionStatus m_connectionStatus;
|
||||
int m_connectionStatusTtl;
|
||||
mutable QTime m_connectionStatusTime;
|
||||
mutable bool m_initialized;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user