mirror of
https://github.com/cculianu/Fulcrum.git
synced 2026-08-15 12:50:49 +02:00
And added some test code in Controller to use the scheme. It's very asynchronous. Needs some tuning long term to see how it deals with load and perhaps throttle the requests if we know bitcoind is under load. But for right now, for testing, it should work ok. Also in this commit small nits, plus bugfix to RPC::Message factory methods (I forgot to populate some instance properties when constructing the objects). Additionally, we were registering the qMetaType wrong for RPC::Message and RPC::Message::Id (this has been fixed).
81 lines
3.3 KiB
C++
81 lines
3.3 KiB
C++
#include "Controller.h"
|
|
|
|
Controller::Controller(const std::shared_ptr<Options> &o)
|
|
: Mgr(nullptr), options(o)
|
|
{
|
|
setObjectName("Controller");
|
|
_thread.setObjectName(objectName());
|
|
}
|
|
|
|
Controller::~Controller() { Debug(__FUNCTION__); cleanup(); }
|
|
|
|
auto Controller::stats() const -> Stats
|
|
{
|
|
auto st = srvmgr->statsSafe();
|
|
Util::updateMap(st, bitcoindmgr->statsSafe());
|
|
return st;
|
|
}
|
|
|
|
void Controller::startup()
|
|
{
|
|
bitcoindmgr = std::make_unique<BitcoinDMgr>(options->bitcoind.first, options->bitcoind.second, options->rpcuser, options->rpcpassword);
|
|
{
|
|
// some setup code that waits for bitcoind to be ready before kicking off our "process" method
|
|
auto waitForBitcoinD = [this] {
|
|
auto constexpr waitTimer = "wait4bitcoind", callProcessTimer = "callProcess";
|
|
int constexpr msgPeriod = 10000, // 10sec
|
|
smallDelay = 100;
|
|
stopTimer(callProcessTimer);
|
|
callOnTimerSoon(msgPeriod, waitTimer, []{ Log("Waiting for bitcoind..."); return true; }, false, Qt::TimerType::VeryCoarseTimer);
|
|
// connection to kick off our 'process' method once the first auth is received
|
|
auto connPtr = std::make_shared<QMetaObject::Connection>();
|
|
*connPtr = connect(bitcoindmgr.get(), &BitcoinDMgr::gotFirstGoodConnection, this, [this, connPtr](quint64 id) mutable {
|
|
if (connPtr) {
|
|
stopTimer(waitTimer);
|
|
if (!disconnect(*connPtr)) Fatal() << "Failed to disconnect 'authenticated' signal! FIXME!"; // this should never happen but if it does, app quits.
|
|
connPtr.reset(); // clear connPtr right away to 1. delte it asap and 2. so we are guaranteed not to reenter this block for this connection should there be a spurious signal emitted.
|
|
Debug() << "Auth recvd from bicoind with id: " << id << ", proceeding with processing ...";
|
|
callOnTimerSoonNoRepeat(smallDelay, callProcessTimer, [this]{process();}, true);
|
|
}
|
|
});
|
|
};
|
|
waitForBitcoinD();
|
|
conns += connect(bitcoindmgr.get(), &BitcoinDMgr::allConnectionsLost, this, waitForBitcoinD);
|
|
}
|
|
|
|
bitcoindmgr->startup(); // may throw
|
|
|
|
srvmgr = std::make_unique<SrvMgr>(options->interfaces, nullptr /* we are not parent so it won't follow us to our thread*/);
|
|
srvmgr->startup(); // may throw Exception, waits for servers to bind
|
|
|
|
start(); // start our thread
|
|
}
|
|
|
|
void Controller::cleanup()
|
|
{
|
|
stop();
|
|
if (srvmgr) { Log("Stopping SrvMgr ... "); srvmgr->cleanup(); srvmgr.reset(); }
|
|
if (bitcoindmgr) { Log("Stopping BitcoinDMgr ... "); bitcoindmgr->cleanup(); bitcoindmgr.reset(); }
|
|
sm.reset();
|
|
}
|
|
|
|
|
|
|
|
struct Controller::StateMachine
|
|
{
|
|
// TODO: put state stuff here
|
|
};
|
|
|
|
void Controller::process()
|
|
{
|
|
Debug() << "Process called...";
|
|
if (!sm) sm = std::make_unique<StateMachine>(); // create statemachine if doest not exist
|
|
|
|
bitcoindmgr->submitRequest(this, IdMixin::newId(), "getmempoolinfo", {}, [](auto resp){ // testing
|
|
Trace() << resp.id.toString() << ": result reply: " << resp.toJsonString();
|
|
}, [](auto resp){
|
|
Trace() << resp.id.toString() << ": error response: " << resp.toJsonString();
|
|
}, [](auto id, auto msg) {
|
|
Warning() << id.toString() << ": FAIL: " << msg;
|
|
});
|
|
}
|