- Refactored Dashboard to send one command to multiple miners and "beautified" dashboard

- Miner now publishs own config to XMRigCCServer on startup
- Added command to trigger miner to upload config to XMRigCCServer
- Added threads to miner info tooltip on client id
This commit is contained in:
BenDroid 2017-12-16 22:38:51 +01:00
parent 67ca2d1520
commit 3b3e1affa3
11 changed files with 475 additions and 239 deletions

View file

@ -22,6 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include <sstream>
#include <fstream>
#include <3rdparty/rapidjson/stringbuffer.h>
#include <3rdparty/rapidjson/prettywriter.h>
@ -83,6 +85,7 @@ CCClient::CCClient(Options* options, uv_async_t* async)
m_clientStatus.setCpuBrand(Cpu::brand());
m_clientStatus.setCpuAES(Cpu::hasAES());
m_clientStatus.setCpuCores(Cpu::cores());
m_clientStatus.setCpuThreads(Cpu::threads());
m_clientStatus.setCpuX64(Cpu::isX64());
m_clientStatus.setCpuL2(Cpu::l2());
@ -159,7 +162,10 @@ void CCClient::publishClientStatusReport()
} else if (controlCommand.getCommand() == ControlCommand::UPDATE_CONFIG) {
LOG_WARN("[CC-Client] Command: UPDATE_CONFIG received -> update config");
updateConfig();
} else if (controlCommand.getCommand() == ControlCommand::RESTART) {
} else if (controlCommand.getCommand() == ControlCommand::PUBLISH_CONFIG) {
LOG_WARN("[CC-Client] Command: PUBLISH_CONFIG received -> publish config");
publishConfig();
}else if (controlCommand.getCommand() == ControlCommand::RESTART) {
LOG_WARN("[CC-Client] Command: RESTART received -> restart");
} else if (controlCommand.getCommand() == ControlCommand::SHUTDOWN) {
LOG_WARN("[CC-Client] Command: SHUTDOWN received -> shutdown");
@ -208,6 +214,44 @@ void CCClient::updateConfig()
}
}
void CCClient::publishConfig()
{
std::string requestUrl = "/client/setClientConfig?clientId=" + m_self->m_clientStatus.getClientId();
std::stringstream data;
std::ifstream clientConfig(m_self->m_options->configFile());
if (clientConfig) {
data << clientConfig.rdbuf();
clientConfig.close();
}
if (data.tellp() > 0) {
rapidjson::Document document;
document.Parse(data.str().c_str());
if (!document.HasParseError()) {
rapidjson::StringBuffer buffer(0, 65536);
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
document.Accept(writer);
auto res = performRequest(requestUrl, buffer.GetString(), "POST");
if (!res) {
LOG_ERR("[CC-Client] error: unable to performRequest POST -> http://%s:%d%s",
m_self->m_options->ccHost(), m_self->m_options->ccPort(), requestUrl.c_str());
} else if (res->status != 200) {
LOG_ERR("[CC-Client] error: \"%d\" -> http://%s:%d%s", res->status, m_self->m_options->ccHost(),
m_self->m_options->ccPort(), requestUrl.c_str());
}
} else {
LOG_ERR("Not able to send config. Client config %s is broken!", m_self->m_options->configFile());
}
} else {
LOG_ERR("Not able to load client config %s. Please make sure it exists!", m_self->m_options->configFile());
}
}
std::shared_ptr<httplib::Response> CCClient::performRequest(const std::string& requestUrl,
const std::string& requestBuffer,
const std::string& operation)
@ -245,6 +289,8 @@ void CCClient::onThreadStarted(void* handle)
static_cast<uint64_t>(m_self->m_options->ccUpdateInterval() * 1000),
static_cast<uint64_t>(m_self->m_options->ccUpdateInterval() * 1000));
publishConfig();
uv_run(&m_self->m_client_loop, UV_RUN_DEFAULT);
}

View file

@ -48,6 +48,7 @@ private:
static void publishClientStatusReport();
static void updateConfig();
static void publishConfig();
static std::shared_ptr<httplib::Response> performRequest(const std::string& requestUrl,
const std::string& requestBuffer,
const std::string& operation);

View file

@ -44,6 +44,7 @@ ClientStatus::ClientStatus()
m_hashrateHighest(0),
m_currentThreads(0),
m_cpuCores(0),
m_cpuThreads(0),
m_cpuL2(0),
m_cpuL3(0),
m_sharesGood(0),
@ -235,6 +236,16 @@ void ClientStatus::setCpuCores(int cpuCores)
m_cpuCores = cpuCores;
}
int ClientStatus::getCpuThreads() const
{
return m_cpuThreads;
}
void ClientStatus::setCpuThreads(int cpuThreads)
{
m_cpuThreads = cpuThreads;
}
int ClientStatus::getCpuL2() const
{
return m_cpuL2;
@ -379,6 +390,10 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document)
m_cpuCores = clientStatus["cpu_cores"].GetInt();
}
if (clientStatus.HasMember("cpu_threads")) {
m_cpuThreads = clientStatus["cpu_threads"].GetInt();
}
if (clientStatus.HasMember("cpu_l2")) {
m_cpuL2 = clientStatus["cpu_l2"].GetInt();
}
@ -440,6 +455,7 @@ rapidjson::Value ClientStatus::toJson(rapidjson::MemoryPoolAllocator<rapidjson::
clientStatus.AddMember("current_threads", m_currentThreads, allocator);
clientStatus.AddMember("cpu_cores", m_cpuCores, allocator);
clientStatus.AddMember("cpu_threads", m_cpuThreads, allocator);
clientStatus.AddMember("cpu_l2", m_cpuL2, allocator);
clientStatus.AddMember("cpu_l3", m_cpuL3, allocator);

View file

@ -112,6 +112,9 @@ public:
int getCpuCores() const;
void setCpuCores(int cpuCores);
int getCpuThreads() const;
void setCpuThreads(int cpuThreads);
int getCpuL2() const;
void setCpuL2(int cpuL2);
@ -166,6 +169,7 @@ private:
int m_currentThreads;
int m_cpuCores;
int m_cpuThreads;
int m_cpuL2;
int m_cpuL3;

View file

@ -94,6 +94,7 @@ ControlCommand::Command ControlCommand::getCommand() const
bool ControlCommand::isOneTimeCommand() const {
return m_command == ControlCommand::UPDATE_CONFIG ||
m_command == ControlCommand::PUBLISH_CONFIG ||
m_command == ControlCommand::RESTART ||
m_command == ControlCommand::SHUTDOWN;
}

View file

@ -28,10 +28,11 @@
#include <string>
#include "rapidjson/document.h"
static const char* command_str[5] = {
static const char* command_str[6] = {
"START",
"STOP",
"UPDATE_CONFIG",
"PUBLISH_CONFIG",
"RESTART",
"SHUTDOWN"
};
@ -43,6 +44,7 @@ public:
START,
STOP,
UPDATE_CONFIG,
PUBLISH_CONFIG,
RESTART,
SHUTDOWN
};

View file

@ -99,7 +99,7 @@ unsigned Service::handlePOST(const Options* options, const std::string& url, con
if (url.rfind("/client/setClientStatus", 0) == 0) {
resultCode = setClientStatus(clientIp, clientId, data, resp);
} else if (url.rfind("/admin/setClientConfig", 0) == 0) {
} else if (url.rfind("/admin/setClientConfig", 0) == 0 || url.rfind("/client/setClientConfig", 0) == 0) {
resultCode = setClientConfig(options, clientId, data, resp);
} else if (url.rfind("/admin/setClientCommand", 0) == 0) {
resultCode = setClientCommand(clientId, data, resp);