From c9d6a44c3a5cc399d115738404e1e7acad332415 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Feb 2015 16:56:13 -0800 Subject: [PATCH 1/8] fix up command-line parsing --- assignment-client/src/AssignmentClient.cpp | 49 ++------ assignment-client/src/AssignmentClient.h | 4 +- assignment-client/src/AssignmentClientApp.cpp | 118 +++++++++++++++++- assignment-client/src/AssignmentClientApp.h | 16 +++ .../src/AssignmentClientMonitor.cpp | 60 ++++++--- .../src/AssignmentClientMonitor.h | 15 ++- 6 files changed, 196 insertions(+), 66 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 2dfc3787de..cb2da51031 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -40,7 +39,9 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); -AssignmentClient::AssignmentClient(int &argc, char **argv) : +AssignmentClient::AssignmentClient(int &argc, char **argv, + Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, + QString assignmentServerHostname, quint16 assignmentServerPort) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), _localASPortSharedMem(NULL), @@ -73,51 +74,20 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // set the logging target to the the CHILD_TARGET_NAME LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); - const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments()); - - const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "t"; - const QString ASSIGNMENT_POOL_OPTION = "pool"; - const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "wallet"; - const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "a"; - const QString CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION = "p"; - - Assignment::Type requestAssignmentType = Assignment::AllTypes; - - // check for an assignment type passed on the command line or in the config - if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { - requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt(); - } - - QString assignmentPool; - - // check for an assignment pool passed on the command line or in the config - if (argumentVariantMap.contains(ASSIGNMENT_POOL_OPTION)) { - assignmentPool = argumentVariantMap.value(ASSIGNMENT_POOL_OPTION).toString(); - } - // setup our _requestAssignment member variable from the passed arguments _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); // check for a wallet UUID on the command line or in the config // this would represent where the user running AC wants funds sent to - if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { - QUuid walletUUID = argumentVariantMap.value(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION).toString(); + if (!walletUUID.isNull()) { qDebug() << "The destination wallet UUID for credits is" << uuidStringWithoutCurlyBraces(walletUUID); _requestAssignment.setWalletUUID(walletUUID); } - quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; - // check for an overriden assignment server hostname - if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) { + if (assignmentServerHostname != "") { // change the hostname for our assignment server - _assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); - } - - // check for an overriden assignment server port - if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) { - assignmentServerPort = - argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt(); + _assignmentServerHostname = assignmentServerHostname; } _assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true); @@ -128,6 +98,10 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required qDebug() << "Waiting for assignment -" << _requestAssignment; + if (_assignmentServerHostname != "localhost") { + qDebug () << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort(); + } + connect(&_requestTimer, SIGNAL(timeout()), SLOT(sendAssignmentRequest())); _requestTimer.start(ASSIGNMENT_REQUEST_INTERVAL_MSECS); @@ -199,9 +173,6 @@ void AssignmentClient::sendAssignmentRequest() { nodeList->setAssignmentServerSocket(_assignmentServerSocket); } } - else { - qDebug () << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort(); - } } nodeList->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index e105309e10..67a5dc89a7 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -21,7 +21,9 @@ class QSharedMemory; class AssignmentClient : public QCoreApplication { Q_OBJECT public: - AssignmentClient(int &argc, char **argv); + + AssignmentClient(int &argc, char **argv, Assignment::Type requestAssignmentType, QString assignmentPool, + QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } private slots: diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 477f1a2cf8..7f174f0833 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "Assignment.h" #include "AssignmentClient.h" @@ -37,9 +38,35 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : const QCommandLineOption helpOption = parser.addHelpOption(); - const QCommandLineOption numChildsOption("n", "number of children to fork", "child-count"); + const QCommandLineOption clientTypeOption(ASSIGNMENT_TYPE_OVERRIDE_OPTION, + "run single assignment client of given type", "type"); + parser.addOption(clientTypeOption); + + const QCommandLineOption poolOption(ASSIGNMENT_POOL_OPTION, "set assignment pool", "pool-name"); + parser.addOption(poolOption); + + const QCommandLineOption walletDestinationOption(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, + "set wallet destination", "wallet-uuid"); + parser.addOption(walletDestinationOption); + + const QCommandLineOption assignmentServerHostnameOption(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, + "set assignment-server hostname", "hostname"); + parser.addOption(assignmentServerHostnameOption); + + const QCommandLineOption assignmentServerPortOption(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION, + "set assignment-server port", "port"); + parser.addOption(assignmentServerPortOption); + + const QCommandLineOption numChildsOption(ASSIGNMENT_NUM_FORKS_OPTION, "number of children to fork", "child-count"); parser.addOption(numChildsOption); + const QCommandLineOption minChildsOption(ASSIGNMENT_MIN_FORKS_OPTION, "minimum number of children", "child-count"); + parser.addOption(minChildsOption); + + const QCommandLineOption maxChildsOption(ASSIGNMENT_MAX_FORKS_OPTION, "maximum number of children", "child-count"); + parser.addOption(maxChildsOption); + + if (!parser.parse(QCoreApplication::arguments())) { qCritical() << parser.errorText() << endl; parser.showHelp(); @@ -51,16 +78,99 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : Q_UNREACHABLE(); } + + const QVariantMap argumentVariantMap = HifiConfigVariantMap::mergeCLParametersWithJSONConfig(arguments()); + + unsigned int numForks = 0; if (parser.isSet(numChildsOption)) { numForks = parser.value(numChildsOption).toInt(); } - if (numForks) { - AssignmentClientMonitor monitor(argc, argv, numForks); + unsigned int minForks = 0; + if (parser.isSet(minChildsOption)) { + minForks = parser.value(minChildsOption).toInt(); + } + + unsigned int maxForks = 0; + if (parser.isSet(maxChildsOption)) { + maxForks = parser.value(maxChildsOption).toInt(); + } + + + Assignment::Type requestAssignmentType = Assignment::AllTypes; + if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { + requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt(); + } + if (parser.isSet(clientTypeOption)) { + if (numForks || minForks || maxForks) { + qCritical() << "don't use -t with forking mode."; + parser.showHelp(); + Q_UNREACHABLE(); + } + requestAssignmentType = (Assignment::Type) parser.value(clientTypeOption).toInt(); + } + + QString assignmentPool; + // check for an assignment pool passed on the command line or in the config + if (argumentVariantMap.contains(ASSIGNMENT_POOL_OPTION)) { + assignmentPool = argumentVariantMap.value(ASSIGNMENT_POOL_OPTION).toString(); + } + if (parser.isSet(poolOption)) { + assignmentPool = parser.value(poolOption); + } + + + QUuid walletUUID; + if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { + walletUUID = argumentVariantMap.value(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION).toString(); + } + if (parser.isSet(walletDestinationOption)) { + walletUUID = parser.value(walletDestinationOption); + } + + + QString assignmentServerHostname; + if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { + assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); + } + if (parser.isSet(assignmentServerHostnameOption)) { + assignmentServerHostname = parser.value(assignmentServerHostnameOption); + } + + + // check for an overriden assignment server port + quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; + if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { + assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt(); + } + if (parser.isSet(assignmentServerPortOption)) { + assignmentServerPort = parser.value(assignmentServerPortOption).toInt(); + } + + + + if (parser.isSet(numChildsOption)) { + if (minForks && minForks > numForks) { + qCritical() << "--min can't be more than -n"; + parser.showHelp(); + Q_UNREACHABLE(); + } + if (maxForks && maxForks < numForks) { + qCritical() << "--max can't be less than -n"; + parser.showHelp(); + Q_UNREACHABLE(); + } + } + + + if (numForks || minForks || maxForks) { + AssignmentClientMonitor monitor(argc, argv, numForks, minForks, maxForks, assignmentPool, + walletUUID, assignmentServerHostname, assignmentServerPort); monitor.exec(); } else { - AssignmentClient client(argc, argv); + AssignmentClient client(argc, argv, requestAssignmentType, assignmentPool, + walletUUID, assignmentServerHostname, assignmentServerPort); client.exec(); } } diff --git a/assignment-client/src/AssignmentClientApp.h b/assignment-client/src/AssignmentClientApp.h index c5099ff25c..531035ef0e 100644 --- a/assignment-client/src/AssignmentClientApp.h +++ b/assignment-client/src/AssignmentClientApp.h @@ -9,10 +9,26 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#ifndef hifi_AssignmentClientApp_h +#define hifi_AssignmentClientApp_h + + #include +const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "t"; +const QString ASSIGNMENT_POOL_OPTION = "pool"; +const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "wallet"; +const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "a"; +const QString CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION = "p"; +const QString ASSIGNMENT_NUM_FORKS_OPTION = "n"; +const QString ASSIGNMENT_MIN_FORKS_OPTION = "min"; +const QString ASSIGNMENT_MAX_FORKS_OPTION = "max"; + + class AssignmentClientApp : public QCoreApplication { Q_OBJECT public: AssignmentClientApp(int argc, char* argv[]); }; + +#endif // hifi_AssignmentClientApp_h diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 803c7fd5c7..0f8e7adc17 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -16,6 +16,7 @@ #include #include "AssignmentClientMonitor.h" +#include "AssignmentClientApp.h" #include "AssignmentClientChildData.h" #include "PacketHeaders.h" #include "SharedUtil.h" @@ -24,8 +25,20 @@ const char* NUM_FORKS_PARAMETER = "-n"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; -AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks) : - QCoreApplication(argc, argv) +AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, + const unsigned int numAssignmentClientForks, + const unsigned int minAssignmentClientForks, + const unsigned int maxAssignmentClientForks, + QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, + quint16 assignmentServerPort) : + QCoreApplication(argc, argv), + _numAssignmentClientForks(numAssignmentClientForks), + _minAssignmentClientForks(minAssignmentClientForks), + _maxAssignmentClientForks(maxAssignmentClientForks), + _assignmentPool(assignmentPool), + _walletUUID(walletUUID), + _assignmentServerHostname(assignmentServerHostname), + _assignmentServerPort(assignmentServerPort) { // start the Logging class with the parent's target name LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); @@ -36,16 +49,6 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, const u #else ShutdownEventListener::getInstance(); #endif - - _childArguments = arguments(); - - // remove the parameter for the number of forks so it isn't passed to the child forked processes - int forksParameterIndex = _childArguments.indexOf(NUM_FORKS_PARAMETER); - - // this removes both the "-n" parameter and the number of forks passed - _childArguments.removeAt(forksParameterIndex); - _childArguments.removeAt(forksParameterIndex); - // create a NodeList so we can receive stats from children DependencyManager::registerInheritance(); @@ -58,7 +61,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, const u nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this); // use QProcess to fork off a process for each of the child assignment clients - for (unsigned int i = 0; i < numAssignmentClientForks; i++) { + for (unsigned int i = 0; i < _numAssignmentClientForks; i++) { spawnChildClient(); } @@ -83,7 +86,26 @@ void AssignmentClientMonitor::stopChildProcesses() { void AssignmentClientMonitor::spawnChildClient() { QProcess *assignmentClient = new QProcess(this); - + + // unparse the parts of the command-line that the child cares about + QStringList _childArguments; + if (_assignmentPool != "") { + _childArguments.append("--" + ASSIGNMENT_POOL_OPTION); + _childArguments.append(_assignmentPool); + } + if (!_walletUUID.isNull()) { + _childArguments.append("--" + ASSIGNMENT_WALLET_DESTINATION_ID_OPTION); + _childArguments.append(_walletUUID.toString()); + } + if (_assignmentServerHostname != "") { + _childArguments.append("--" + CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); + _childArguments.append(_assignmentServerHostname); + } + if (_assignmentServerPort != DEFAULT_DOMAIN_SERVER_PORT) { + _childArguments.append("--" + CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION); + _childArguments.append(QString::number(_assignmentServerPort)); + } + // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); @@ -98,26 +120,24 @@ void AssignmentClientMonitor::checkSpares() { auto nodeList = DependencyManager::get(); QUuid aSpareId = ""; unsigned int spareCount = 0; + unsigned int totalCount = 0; nodeList->removeSilentNodes(); nodeList->eachNode([&](const SharedNodePointer& node) { AssignmentClientChildData *childData = static_cast(node->getLinkedData()); + totalCount ++; if (childData->getChildType() == "none") { spareCount ++; aSpareId = node->getUUID(); } }); - if (spareCount != 1) { - qDebug() << "spare count is" << spareCount; - } - - if (spareCount < 1) { + if (spareCount < 1 && totalCount < _maxAssignmentClientForks) { spawnChildClient(); } - if (spareCount > 1) { + if (spareCount > 1 && totalCount > _minAssignmentClientForks) { // kill aSpareId qDebug() << "asking child" << aSpareId << "to exit."; SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId); diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 71ae34bc8c..e40a10014b 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -27,7 +27,10 @@ extern const char* NUM_FORKS_PARAMETER; class AssignmentClientMonitor : public QCoreApplication { Q_OBJECT public: - AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks); + AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks, + const unsigned int minAssignmentClientForks, const unsigned int maxAssignmentClientForks, + QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, + quint16 assignmentServerPort); ~AssignmentClientMonitor(); void stopChildProcesses(); @@ -37,8 +40,16 @@ private slots: private: void spawnChildClient(); - QStringList _childArguments; QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children + + const unsigned int _numAssignmentClientForks; + const unsigned int _minAssignmentClientForks; + const unsigned int _maxAssignmentClientForks; + + QString _assignmentPool; + QUuid _walletUUID; + QString _assignmentServerHostname; + quint16 _assignmentServerPort; }; #endif // hifi_AssignmentClientMonitor_h From 89ebb45c0390830c84e41c12bf865a84a3792b86 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Feb 2015 17:09:05 -0800 Subject: [PATCH 2/8] Revert "Merge pull request #4332 from birarda/master" This reverts commit 3230857b0d03c603bacb9016740234e781070d44, reversing changes made to 1b669af79df5335ae0e6565c33e06e30a006ca5e. --- assignment-client/src/AssignmentClient.cpp | 87 +++++++--- assignment-client/src/AssignmentClient.h | 11 +- assignment-client/src/AssignmentClientApp.cpp | 66 ++++++++ assignment-client/src/AssignmentClientApp.h | 18 ++ .../src/AssignmentClientChildData.cpp | 8 + .../src/AssignmentClientChildData.h | 32 ++++ .../src/AssignmentClientMonitor.cpp | 158 ++++++++++++++---- .../src/AssignmentClientMonitor.h | 13 +- assignment-client/src/main.cpp | 30 +--- domain-server/src/DomainServer.cpp | 14 +- libraries/networking/src/AddressManager.cpp | 4 +- libraries/networking/src/LimitedNodeList.cpp | 38 +++++ libraries/networking/src/LimitedNodeList.h | 9 + libraries/networking/src/Node.cpp | 7 +- libraries/networking/src/NodeList.cpp | 8 +- libraries/networking/src/NodeList.h | 1 + libraries/networking/src/PacketHeaders.cpp | 3 + libraries/networking/src/PacketHeaders.h | 4 +- 18 files changed, 403 insertions(+), 108 deletions(-) create mode 100644 assignment-client/src/AssignmentClientApp.cpp create mode 100644 assignment-client/src/AssignmentClientApp.h create mode 100644 assignment-client/src/AssignmentClientChildData.cpp create mode 100644 assignment-client/src/AssignmentClientChildData.h diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index bf67d4d597..2dfc3787de 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -18,10 +18,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -43,7 +43,8 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), - _localASPortSharedMem(NULL) + _localASPortSharedMem(NULL), + _localACMPortSharedMem(NULL) { LogUtils::init(); @@ -56,7 +57,11 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : DependencyManager::registerInheritance(); auto addressManager = DependencyManager::set(); auto nodeList = DependencyManager::set(NodeType::Unassigned); - auto avatarHashMap = DependencyManager::set(); + + // make up a uuid for this child so the parent can tell us apart. This id will be changed + // when the domain server hands over an assignment. + QUuid nodeUUID = QUuid::createUuid(); + nodeList->setSessionUUID(nodeUUID); // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us #ifdef _WIN32 @@ -123,9 +128,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required qDebug() << "Waiting for assignment -" << _requestAssignment; - QTimer* timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), SLOT(sendAssignmentRequest())); - timer->start(ASSIGNMENT_REQUEST_INTERVAL_MSECS); + connect(&_requestTimer, SIGNAL(timeout()), SLOT(sendAssignmentRequest())); + _requestTimer.start(ASSIGNMENT_REQUEST_INTERVAL_MSECS); // connect our readPendingDatagrams method to the readyRead() signal of the socket connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams); @@ -136,6 +140,45 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // Create Singleton objects on main thread NetworkAccessManager::getInstance(); + + // Hook up a timer to send this child's status to the Monitor once per second + setUpStatsToMonitor(); +} + + +void AssignmentClient::stopAssignmentClient() { + qDebug() << "Exiting."; + _requestTimer.stop(); + _statsTimerACM.stop(); + quit(); +} + + +void AssignmentClient::setUpStatsToMonitor() { + // Figure out the address to send out stats to + quint16 localMonitorServerPort = DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT; + auto nodeList = DependencyManager::get(); + + nodeList->getLocalServerPortFromSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, + _localACMPortSharedMem, localMonitorServerPort); + _assignmentClientMonitorSocket = HifiSockAddr(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME, localMonitorServerPort, true); + + // send a stats packet every 1 seconds + connect(&_statsTimerACM, &QTimer::timeout, this, &AssignmentClient::sendStatsPacketToACM); + _statsTimerACM.start(1000); +} + +void AssignmentClient::sendStatsPacketToACM() { + // tell the assignment client monitor what this assignment client is doing (if anything) + QJsonObject statsObject; + auto nodeList = DependencyManager::get(); + + if (_currentAssignment) { + statsObject["assignment_type"] = _currentAssignment->getTypeName(); + } else { + statsObject["assignment_type"] = "none"; + } + nodeList->sendStats(statsObject, _assignmentClientMonitorSocket); } void AssignmentClient::sendAssignmentRequest() { @@ -145,23 +188,9 @@ void AssignmentClient::sendAssignmentRequest() { if (_assignmentServerHostname == "localhost") { // we want to check again for the local domain-server port in case the DS has restarted - if (!_localASPortSharedMem) { - _localASPortSharedMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this); - - if (!_localASPortSharedMem->attach(QSharedMemory::ReadOnly)) { - qWarning() << "Could not attach to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY - << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort(); - } - } - - if (_localASPortSharedMem->isAttached()) { - _localASPortSharedMem->lock(); - - quint16 localAssignmentServerPort; - memcpy(&localAssignmentServerPort, _localASPortSharedMem->data(), sizeof(localAssignmentServerPort)); - - _localASPortSharedMem->unlock(); - + quint16 localAssignmentServerPort; + if (nodeList->getLocalServerPortFromSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, _localASPortSharedMem, + localAssignmentServerPort)) { if (localAssignmentServerPort != _assignmentServerSocket.getPort()) { qDebug() << "Port for local assignment server read from shared memory is" << localAssignmentServerPort; @@ -170,7 +199,9 @@ void AssignmentClient::sendAssignmentRequest() { nodeList->setAssignmentServerSocket(_assignmentServerSocket); } } - + else { + qDebug () << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort(); + } } nodeList->sendAssignment(_requestAssignment); @@ -227,6 +258,14 @@ void AssignmentClient::readPendingDatagrams() { } else { qDebug() << "Received an assignment that could not be unpacked. Re-requesting."; } + } else if (packetTypeForPacket(receivedPacket) == PacketTypeStopNode) { + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || + senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + qDebug() << "Network told me to exit."; + emit stopAssignmentClient(); + } else { + qDebug() << "Got a stop packet from other than localhost."; + } } else { // have the NodeList attempt to handle it nodeList->processNodeData(senderSockAddr, receivedPacket); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 053458f136..e105309e10 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -29,13 +29,22 @@ private slots: void readPendingDatagrams(); void assignmentCompleted(); void handleAuthenticationRequest(); + void sendStatsPacketToACM(); + void stopAssignmentClient(); private: + void setUpStatsToMonitor(); Assignment _requestAssignment; static SharedAssignmentPointer _currentAssignment; QString _assignmentServerHostname; HifiSockAddr _assignmentServerSocket; - QSharedMemory* _localASPortSharedMem; + QSharedMemory* _localASPortSharedMem; // memory shared with domain server + QSharedMemory* _localACMPortSharedMem; // memory shared with assignment client monitor + QTimer _requestTimer; // timer for requesting and assignment + QTimer _statsTimerACM; // timer for sending stats to assignment client monitor + + protected: + HifiSockAddr _assignmentClientMonitorSocket; }; #endif // hifi_AssignmentClient_h diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp new file mode 100644 index 0000000000..477f1a2cf8 --- /dev/null +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -0,0 +1,66 @@ +// +// AssignmentClientapp.cpp +// assignment-client/src +// +// Created by Seth Alves on 2/19/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include + +#include "Assignment.h" +#include "AssignmentClient.h" +#include "AssignmentClientMonitor.h" +#include "AssignmentClientApp.h" + + +AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : + QCoreApplication(argc, argv) +{ +# ifndef WIN32 + setvbuf(stdout, NULL, _IOLBF, 0); +# endif + + // use the verbose message handler in Logging + qInstallMessageHandler(LogHandler::verboseMessageHandler); + + // parse command-line + QCommandLineParser parser; + parser.setApplicationDescription("High Fidelity Assignment Client"); + parser.addHelpOption(); + + const QCommandLineOption helpOption = parser.addHelpOption(); + + const QCommandLineOption numChildsOption("n", "number of children to fork", "child-count"); + parser.addOption(numChildsOption); + + if (!parser.parse(QCoreApplication::arguments())) { + qCritical() << parser.errorText() << endl; + parser.showHelp(); + Q_UNREACHABLE(); + } + + if (parser.isSet(helpOption)) { + parser.showHelp(); + Q_UNREACHABLE(); + } + + unsigned int numForks = 0; + if (parser.isSet(numChildsOption)) { + numForks = parser.value(numChildsOption).toInt(); + } + + if (numForks) { + AssignmentClientMonitor monitor(argc, argv, numForks); + monitor.exec(); + } else { + AssignmentClient client(argc, argv); + client.exec(); + } +} diff --git a/assignment-client/src/AssignmentClientApp.h b/assignment-client/src/AssignmentClientApp.h new file mode 100644 index 0000000000..c5099ff25c --- /dev/null +++ b/assignment-client/src/AssignmentClientApp.h @@ -0,0 +1,18 @@ +// +// AssignmentClientapp.h +// assignment-client/src +// +// Created by Seth Alves on 2/19/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +class AssignmentClientApp : public QCoreApplication { + Q_OBJECT +public: + AssignmentClientApp(int argc, char* argv[]); +}; diff --git a/assignment-client/src/AssignmentClientChildData.cpp b/assignment-client/src/AssignmentClientChildData.cpp new file mode 100644 index 0000000000..de34613ec9 --- /dev/null +++ b/assignment-client/src/AssignmentClientChildData.cpp @@ -0,0 +1,8 @@ + +#include "AssignmentClientChildData.h" + + +AssignmentClientChildData::AssignmentClientChildData(QString childType) : + _childType(childType) +{ +} diff --git a/assignment-client/src/AssignmentClientChildData.h b/assignment-client/src/AssignmentClientChildData.h new file mode 100644 index 0000000000..6fd5f72f7f --- /dev/null +++ b/assignment-client/src/AssignmentClientChildData.h @@ -0,0 +1,32 @@ +// +// AssignmentClientChildData.h +// assignment-client/src +// +// Created by Seth Alves on 2/23/2015. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AssignmentClientChildData_h +#define hifi_AssignmentClientChildData_h + +#include + + +class AssignmentClientChildData : public NodeData { + public: + AssignmentClientChildData(QString childType); + + QString getChildType() { return _childType; } + void setChildType(QString childType) { _childType = childType; } + + // implement parseData to return 0 so we can be a subclass of NodeData + int parseData(const QByteArray& packet) { return 0; } + + private: + QString _childType; +}; + +#endif // hifi_AssignmentClientChildData_h diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 45e1f56d53..803c7fd5c7 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -13,14 +13,18 @@ #include #include +#include #include "AssignmentClientMonitor.h" +#include "AssignmentClientChildData.h" +#include "PacketHeaders.h" +#include "SharedUtil.h" const char* NUM_FORKS_PARAMETER = "-n"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; -AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) : +AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks) : QCoreApplication(argc, argv) { // start the Logging class with the parent's target name @@ -41,11 +45,25 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num // this removes both the "-n" parameter and the number of forks passed _childArguments.removeAt(forksParameterIndex); _childArguments.removeAt(forksParameterIndex); + + + // create a NodeList so we can receive stats from children + DependencyManager::registerInheritance(); + auto addressManager = DependencyManager::set(); + auto nodeList = DependencyManager::set(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT, + DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT); + + connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams); + + nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this); // use QProcess to fork off a process for each of the child assignment clients - for (int i = 0; i < numAssignmentClientForks; i++) { + for (unsigned int i = 0; i < numAssignmentClientForks; i++) { spawnChildClient(); } + + connect(&_checkSparesTimer, SIGNAL(timeout()), SLOT(checkSpares())); + _checkSparesTimer.start(NODE_SILENCE_THRESHOLD_MSECS * 3); } AssignmentClientMonitor::~AssignmentClientMonitor() { @@ -53,46 +71,122 @@ AssignmentClientMonitor::~AssignmentClientMonitor() { } void AssignmentClientMonitor::stopChildProcesses() { - - QList >::Iterator it = _childProcesses.begin(); - while (it != _childProcesses.end()) { - if (!it->isNull()) { - qDebug() << "Monitor is terminating child process" << it->data(); - - // don't re-spawn this child when it goes down - disconnect(it->data(), 0, this, 0); - - it->data()->terminate(); - it->data()->waitForFinished(); - } - - it = _childProcesses.erase(it); - } + auto nodeList = DependencyManager::get(); + + nodeList->eachNode([&](const SharedNodePointer& node) { + qDebug() << "asking child" << node->getUUID() << "to exit."; + node->activateLocalSocket(); + QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode); + nodeList->writeUnverifiedDatagram(diePacket, *node->getActiveSocket()); + }); } void AssignmentClientMonitor::spawnChildClient() { QProcess *assignmentClient = new QProcess(this); - _childProcesses.append(QPointer(assignmentClient)); - // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); assignmentClient->start(applicationFilePath(), _childArguments); - - // link the child processes' finished slot to our childProcessFinished slot - connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this, - SLOT(childProcessFinished(int, QProcess::ExitStatus))); - + qDebug() << "Spawned a child client with PID" << assignmentClient->pid(); } -void AssignmentClientMonitor::childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { - qDebug("Replacing dead child assignment client with a new one"); - - // remove the old process from our list of child processes - qDebug() << "need to remove" << QPointer(qobject_cast(sender())); - _childProcesses.removeOne(QPointer(qobject_cast(sender()))); - - spawnChildClient(); + + +void AssignmentClientMonitor::checkSpares() { + auto nodeList = DependencyManager::get(); + QUuid aSpareId = ""; + unsigned int spareCount = 0; + + nodeList->removeSilentNodes(); + + nodeList->eachNode([&](const SharedNodePointer& node) { + AssignmentClientChildData *childData = static_cast(node->getLinkedData()); + if (childData->getChildType() == "none") { + spareCount ++; + aSpareId = node->getUUID(); + } + }); + + if (spareCount != 1) { + qDebug() << "spare count is" << spareCount; + } + + if (spareCount < 1) { + spawnChildClient(); + } + + if (spareCount > 1) { + // kill aSpareId + qDebug() << "asking child" << aSpareId << "to exit."; + SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId); + childNode->activateLocalSocket(); + QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode); + nodeList->writeUnverifiedDatagram(diePacket, childNode); + } } + + +void AssignmentClientMonitor::readPendingDatagrams() { + auto nodeList = DependencyManager::get(); + + QByteArray receivedPacket; + HifiSockAddr senderSockAddr; + + while (nodeList->getNodeSocket().hasPendingDatagrams()) { + receivedPacket.resize(nodeList->getNodeSocket().pendingDatagramSize()); + nodeList->getNodeSocket().readDatagram(receivedPacket.data(), receivedPacket.size(), + senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + + if (nodeList->packetVersionAndHashMatch(receivedPacket)) { + if (packetTypeForPacket(receivedPacket) == PacketTypeNodeJsonStats) { + QUuid packetUUID = uuidFromPacketHeader(receivedPacket); + SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); + if (!matchingNode) { + // The parent only expects to be talking with prorams running on this same machine. + if (senderSockAddr.getAddress() == QHostAddress::LocalHost || + senderSockAddr.getAddress() == QHostAddress::LocalHostIPv6) { + if (!packetUUID.isNull()) { + matchingNode = DependencyManager::get()->addOrUpdateNode + (packetUUID, NodeType::Unassigned, senderSockAddr, senderSockAddr, false); + AssignmentClientChildData *childData = new AssignmentClientChildData("unknown"); + matchingNode->setLinkedData(childData); + } else { + // tell unknown assignment-client child to exit. + qDebug() << "asking unknown child to exit."; + QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode); + nodeList->writeUnverifiedDatagram(diePacket, senderSockAddr); + } + } + } + + if (matchingNode) { + // update our records about how to reach this child + matchingNode->setLocalSocket(senderSockAddr); + + // push past the packet header + QDataStream packetStream(receivedPacket); + packetStream.skipRawData(numBytesForPacketHeader(receivedPacket)); + // decode json + QVariantMap unpackedVariantMap; + packetStream >> unpackedVariantMap; + QJsonObject unpackedStatsJSON = QJsonObject::fromVariantMap(unpackedVariantMap); + + // get child's assignment type out of the decoded json + QString childType = unpackedStatsJSON["assignment_type"].toString(); + AssignmentClientChildData *childData = + static_cast(matchingNode->getLinkedData()); + childData->setChildType(childType); + // note when this child talked + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + } + } else { + // have the NodeList attempt to handle it + nodeList->processNodeData(senderSockAddr, receivedPacket); + } + } + } +} + + diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 9a7bca9cb3..71ae34bc8c 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -15,25 +15,30 @@ #include #include #include +#include #include +#include "AssignmentClientChildData.h" + extern const char* NUM_FORKS_PARAMETER; + class AssignmentClientMonitor : public QCoreApplication { Q_OBJECT public: - AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks); + AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks); ~AssignmentClientMonitor(); void stopChildProcesses(); private slots: - void childProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void readPendingDatagrams(); + void checkSpares(); + private: void spawnChildClient(); - QList > _childProcesses; - QStringList _childArguments; + QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children }; #endif // hifi_AssignmentClientMonitor_h diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 3bf6990a74..81a12526bf 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -9,34 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include -#include -#include "Assignment.h" -#include "AssignmentClient.h" -#include "AssignmentClientMonitor.h" +#include "AssignmentClientApp.h" int main(int argc, char* argv[]) { -#ifndef WIN32 - setvbuf(stdout, NULL, _IOLBF, 0); -#endif - - // use the verbose message handler in Logging - qInstallMessageHandler(LogHandler::verboseMessageHandler); - - const char* numForksString = getCmdOption(argc, (const char**)argv, NUM_FORKS_PARAMETER); - - int numForks = 0; - - if (numForksString) { - numForks = atoi(numForksString); - } - - if (numForks) { - AssignmentClientMonitor monitor(argc, argv, numForks); - return monitor.exec(); - } else { - AssignmentClient client(argc, argv); - return client.exec(); - } + AssignmentClientApp app(argc, argv); + return 0; } diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index f84722a438..64e0d335b1 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -246,19 +246,7 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { auto nodeList = DependencyManager::set(domainServerPort, domainServerDTLSPort); // no matter the local port, save it to shared mem so that local assignment clients can ask what it is - QSharedMemory* sharedPortMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this); - quint16 localPort = nodeList->getNodeSocket().localPort(); - - // attempt to create the shared memory segment - if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) { - sharedPortMem->lock(); - memcpy(sharedPortMem->data(), &localPort, sizeof(localPort)); - sharedPortMem->unlock(); - - qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY; - } else { - qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children."; - } + nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this); // set our LimitedNodeList UUID to match the UUID from our config // nodes will currently use this to add resources to data-web that relate to our domain diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 9bcdcbe9a4..f67abdca2b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -76,7 +76,7 @@ const QString AddressManager::currentPath(bool withOrientation) const { pathString += "/" + orientationString; } else { qDebug() << "Cannot add orientation to path without a getter for position." - << "Call AdressManager::setOrientationGetter to pass a function that will return a glm::quat"; + << "Call AddressManager::setOrientationGetter to pass a function that will return a glm::quat"; } } @@ -84,7 +84,7 @@ const QString AddressManager::currentPath(bool withOrientation) const { return pathString; } else { qDebug() << "Cannot create address path without a getter for position." - << "Call AdressManager::setPositionGetter to pass a function that will return a const glm::vec3&"; + << "Call AddressManager::setPositionGetter to pass a function that will return a const glm::vec3&"; return QString(); } } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c8c454ff14..b240f0df9e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -669,3 +669,41 @@ void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSock writeUnverifiedDatagram(iceRequestByteArray, iceServerSockAddr); } + +void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* parent) { + // save our local port to shared memory so that assignment client children know how to talk to this parent + QSharedMemory* sharedPortMem = new QSharedMemory(key, parent); + quint16 localPort = getNodeSocket().localPort(); + + // attempt to create the shared memory segment + if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) { + sharedPortMem->lock(); + memcpy(sharedPortMem->data(), &localPort, sizeof(localPort)); + sharedPortMem->unlock(); + + qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << key; + } else { + qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children."; + } +} + + +bool LimitedNodeList::getLocalServerPortFromSharedMemory(const QString key, QSharedMemory*& sharedMem, + quint16& localPort) { + if (!sharedMem) { + sharedMem = new QSharedMemory(key, this); + + if (!sharedMem->attach(QSharedMemory::ReadOnly)) { + qWarning() << "Could not attach to shared memory at key" << key; + } + } + + if (sharedMem->isAttached()) { + sharedMem->lock(); + memcpy(&localPort, sharedMem->data(), sizeof(localPort)); + sharedMem->unlock(); + return true; + } + + return false; +} diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 72aefdb2b3..02234ee4f7 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -49,6 +50,11 @@ const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io"; const unsigned short STUN_SERVER_PORT = 3478; const QString DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY = "domain-server.local-port"; +const QString ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY = "assignment-client-monitor.local-port"; + +const char DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME[] = "localhost"; +const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT = 40104; +const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT = 40105; class HifiSockAddr; @@ -168,6 +174,9 @@ public: return SharedNodePointer(); } + + void putLocalPortIntoSharedMemory(const QString key, QObject* parent); + bool getLocalServerPortFromSharedMemory(const QString key, QSharedMemory*& sharedMem, quint16& localPort); public slots: void reset(); diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index 2bf792c6ee..2a38799707 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -149,7 +149,12 @@ QDataStream& operator>>(QDataStream& in, Node& node) { } QDebug operator<<(QDebug debug, const Node &node) { - debug.nospace() << NodeType::getNodeTypeName(node.getType()) << " (" << node.getType() << ")"; + debug.nospace() << NodeType::getNodeTypeName(node.getType()); + if (node.getType() == NodeType::Unassigned) { + debug.nospace() << " (1)"; + } else { + debug.nospace() << " (" << node.getType() << ")"; + } debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " "; debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); return debug.nospace(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index f70c2d9b3c..e63f230f6e 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -62,13 +62,17 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); } -qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { +qint64 NodeList::sendStats(const QJsonObject& statsObject, HifiSockAddr destination) { QByteArray statsPacket = byteArrayWithPopulatedHeader(PacketTypeNodeJsonStats); QDataStream statsPacketStream(&statsPacket, QIODevice::Append); statsPacketStream << statsObject.toVariantMap(); - return writeUnverifiedDatagram(statsPacket, _domainHandler.getSockAddr()); + return writeUnverifiedDatagram(statsPacket, destination); +} + +qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) { + return sendStats(statsObject, _domainHandler.getSockAddr()); } void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 907fccfcac..1c6de4bb6c 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -47,6 +47,7 @@ public: NodeType_t getOwnerType() const { return _ownerType; } void setOwnerType(NodeType_t ownerType) { _ownerType = ownerType; } + qint64 sendStats(const QJsonObject& statsObject, HifiSockAddr destination); qint64 sendStatsToDomainServer(const QJsonObject& statsObject); int getNumNoReplyDomainCheckIns() const { return _numNoReplyDomainCheckIns; } diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 2eee540fff..db97e216ee 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -70,6 +70,8 @@ PacketVersion versionForPacketType(PacketType type) { return 2; case PacketTypeOctreeStats: return 1; + case PacketTypeStopNode: + return 1; case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: return VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE; @@ -124,6 +126,7 @@ QString nameForPacketType(PacketType type) { PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityErase); PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityAddResponse); PACKET_TYPE_NAME_LOOKUP(PacketTypeOctreeDataNack); + PACKET_TYPE_NAME_LOOKUP(PacketTypeStopNode); PACKET_TYPE_NAME_LOOKUP(PacketTypeAudioEnvironment); PACKET_TYPE_NAME_LOOKUP(PacketTypeEntityEditNack); PACKET_TYPE_NAME_LOOKUP(PacketTypeSignedTransactionPayment); diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index e593955b51..32f33c01d9 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -67,7 +67,7 @@ enum PacketType { PacketTypeEntityErase, PacketTypeEntityAddResponse, PacketTypeOctreeDataNack, // 45 - UNUSED_10, + PacketTypeStopNode, PacketTypeAudioEnvironment, PacketTypeEntityEditNack, PacketTypeSignedTransactionPayment, @@ -86,7 +86,7 @@ const QSet NON_VERIFIED_PACKETS = QSet() << PacketTypeNodeJsonStats << PacketTypeEntityQuery << PacketTypeOctreeDataNack << PacketTypeEntityEditNack << PacketTypeIceServerHeartbeat << PacketTypeIceServerHeartbeatResponse - << PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply; + << PacketTypeUnverifiedPing << PacketTypeUnverifiedPingReply << PacketTypeStopNode; const int NUM_BYTES_MD5_HASH = 16; const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID; From 5c5ffc07ab4830518735f159d9388c74412dadeb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 24 Feb 2015 17:43:08 -0800 Subject: [PATCH 3/8] allow client count to drift as needed if the user doesn't specify --min or --max --- .../src/AssignmentClientMonitor.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 0f8e7adc17..a3eb5170d5 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -133,17 +133,23 @@ void AssignmentClientMonitor::checkSpares() { } }); - if (spareCount < 1 && totalCount < _maxAssignmentClientForks) { - spawnChildClient(); + // Spawn or kill children, as needed. If --min or --max weren't specified, allow the child count + // to drift up or down as far as needed. + if (spareCount < 1) { + if (!_maxAssignmentClientForks || totalCount < _maxAssignmentClientForks) { + spawnChildClient(); + } } - if (spareCount > 1 && totalCount > _minAssignmentClientForks) { - // kill aSpareId - qDebug() << "asking child" << aSpareId << "to exit."; - SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId); - childNode->activateLocalSocket(); - QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode); - nodeList->writeUnverifiedDatagram(diePacket, childNode); + if (spareCount > 1) { + if (!_minAssignmentClientForks || totalCount > _minAssignmentClientForks) { + // kill aSpareId + qDebug() << "asking child" << aSpareId << "to exit."; + SharedNodePointer childNode = nodeList->nodeWithUUID(aSpareId); + childNode->activateLocalSocket(); + QByteArray diePacket = byteArrayWithPopulatedHeader(PacketTypeStopNode); + nodeList->writeUnverifiedDatagram(diePacket, childNode); + } } } From 0ce49888ff70885e200a50161a5b513713c276f0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 Feb 2015 09:20:34 -0800 Subject: [PATCH 4/8] AssignmentClientApp is QCoreApplication, other classes aren't. If --min is set and all the assignment clients exit (probably due to domain server restarting), respawn until --min is statisfied. --- assignment-client/src/AssignmentClient.cpp | 9 ++------- assignment-client/src/AssignmentClient.h | 4 ++-- assignment-client/src/AssignmentClientApp.cpp | 16 ++++++++++++---- .../src/AssignmentClientMonitor.cpp | 8 +++----- assignment-client/src/AssignmentClientMonitor.h | 9 ++++----- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index cb2da51031..38f5c7cc55 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -39,19 +39,14 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); -AssignmentClient::AssignmentClient(int &argc, char **argv, - Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, +AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort) : - QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), _localASPortSharedMem(NULL), _localACMPortSharedMem(NULL) { LogUtils::init(); - setOrganizationName("High Fidelity"); - setOrganizationDomain("highfidelity.io"); - setApplicationName("assignment-client"); QSettings::setDefaultFormat(QSettings::IniFormat); // create a NodeList as an unassigned client @@ -124,7 +119,7 @@ void AssignmentClient::stopAssignmentClient() { qDebug() << "Exiting."; _requestTimer.stop(); _statsTimerACM.stop(); - quit(); + QCoreApplication::quit(); } diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 67a5dc89a7..d1d93c78dc 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -18,11 +18,11 @@ class QSharedMemory; -class AssignmentClient : public QCoreApplication { +class AssignmentClient : public QObject { Q_OBJECT public: - AssignmentClient(int &argc, char **argv, Assignment::Type requestAssignmentType, QString assignmentPool, + AssignmentClient(Assignment::Type requestAssignmentType, QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 7f174f0833..26b6b8675a 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -28,6 +28,10 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : setvbuf(stdout, NULL, _IOLBF, 0); # endif + setOrganizationName("High Fidelity"); + setOrganizationDomain("highfidelity.io"); + setApplicationName("assignment-client"); + // use the verbose message handler in Logging qInstallMessageHandler(LogHandler::verboseMessageHandler); @@ -97,6 +101,10 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : maxForks = parser.value(maxChildsOption).toInt(); } + if (!numForks && minForks) { + // if the user specified --min but not -n, set -n to --min + numForks = minForks; + } Assignment::Type requestAssignmentType = Assignment::AllTypes; if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { @@ -165,12 +173,12 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : if (numForks || minForks || maxForks) { - AssignmentClientMonitor monitor(argc, argv, numForks, minForks, maxForks, assignmentPool, + AssignmentClientMonitor monitor(numForks, minForks, maxForks, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); - monitor.exec(); + exec(); } else { - AssignmentClient client(argc, argv, requestAssignmentType, assignmentPool, + AssignmentClient client(requestAssignmentType, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); - client.exec(); + exec(); } } diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index a3eb5170d5..29fda05ee1 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -25,13 +25,11 @@ const char* NUM_FORKS_PARAMETER = "-n"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; -AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, - const unsigned int numAssignmentClientForks, +AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, const unsigned int maxAssignmentClientForks, QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort) : - QCoreApplication(argc, argv), _numAssignmentClientForks(numAssignmentClientForks), _minAssignmentClientForks(minAssignmentClientForks), _maxAssignmentClientForks(maxAssignmentClientForks), @@ -109,7 +107,7 @@ void AssignmentClientMonitor::spawnChildClient() { // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); - assignmentClient->start(applicationFilePath(), _childArguments); + assignmentClient->start(QCoreApplication::applicationFilePath(), _childArguments); qDebug() << "Spawned a child client with PID" << assignmentClient->pid(); } @@ -135,7 +133,7 @@ void AssignmentClientMonitor::checkSpares() { // Spawn or kill children, as needed. If --min or --max weren't specified, allow the child count // to drift up or down as far as needed. - if (spareCount < 1) { + if (spareCount < 1 || totalCount < _minAssignmentClientForks) { if (!_maxAssignmentClientForks || totalCount < _maxAssignmentClientForks) { spawnChildClient(); } diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index e40a10014b..dc88bfcd95 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -24,13 +24,12 @@ extern const char* NUM_FORKS_PARAMETER; -class AssignmentClientMonitor : public QCoreApplication { +class AssignmentClientMonitor : public QObject { Q_OBJECT public: - AssignmentClientMonitor(int &argc, char **argv, const unsigned int numAssignmentClientForks, - const unsigned int minAssignmentClientForks, const unsigned int maxAssignmentClientForks, - QString assignmentPool, QUuid walletUUID, QString assignmentServerHostname, - quint16 assignmentServerPort); + AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, + const unsigned int maxAssignmentClientForks, QString assignmentPool, QUuid walletUUID, + QString assignmentServerHostname, quint16 assignmentServerPort); ~AssignmentClientMonitor(); void stopChildProcesses(); From 0918d4989b342f9380e77dc6cd2e00cbaa0483df Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Feb 2015 09:53:23 -0800 Subject: [PATCH 5/8] mv ShutdownEventListener into class which is a child of QCoreApplication --- assignment-client/src/AssignmentClientApp.cpp | 8 ++++++++ assignment-client/src/AssignmentClientMonitor.cpp | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 26b6b8675a..6e269f35b7 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "Assignment.h" #include "AssignmentClient.h" @@ -173,6 +174,13 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : if (numForks || minForks || maxForks) { + // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us +# ifdef _WIN32 + installNativeEventFilter(&ShutdownEventListener::getInstance()); +# else + ShutdownEventListener::getInstance(); +# endif + AssignmentClientMonitor monitor(numForks, minForks, maxForks, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 29fda05ee1..ffc402c04d 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include "AssignmentClientMonitor.h" @@ -40,13 +39,6 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen { // start the Logging class with the parent's target name LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); - - // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us -#ifdef _WIN32 - installNativeEventFilter(&ShutdownEventListener::getInstance()); -#else - ShutdownEventListener::getInstance(); -#endif // create a NodeList so we can receive stats from children DependencyManager::registerInheritance(); From 7c7d727b55a878d4a3610dff083be0067502f5cb Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Feb 2015 10:07:48 -0800 Subject: [PATCH 6/8] mv ShutdownEventListener into class which is a child of QCoreApplication --- assignment-client/src/AssignmentClient.cpp | 7 ------- assignment-client/src/AssignmentClientApp.cpp | 15 +++++++++------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 38f5c7cc55..86680d2f03 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -58,13 +58,6 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri // when the domain server hands over an assignment. QUuid nodeUUID = QUuid::createUuid(); nodeList->setSessionUUID(nodeUUID); - - // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us -#ifdef _WIN32 - installNativeEventFilter(&ShutdownEventListener::getInstance()); -#else - ShutdownEventListener::getInstance(); -#endif // set the logging target to the the CHILD_TARGET_NAME LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 6e269f35b7..7c6fb50db2 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -29,6 +29,14 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : setvbuf(stdout, NULL, _IOLBF, 0); # endif + +# ifdef _WIN32 + installNativeEventFilter(&ShutdownEventListener::getInstance()); +# else + ShutdownEventListener::getInstance(); +# endif + + setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); @@ -175,16 +183,11 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : if (numForks || minForks || maxForks) { // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us -# ifdef _WIN32 - installNativeEventFilter(&ShutdownEventListener::getInstance()); -# else - ShutdownEventListener::getInstance(); -# endif - AssignmentClientMonitor monitor(numForks, minForks, maxForks, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); } else { + // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us AssignmentClient client(requestAssignmentType, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); From c80995170af3a813a8f0885c9c6f825348c9e7c7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Feb 2015 17:17:19 -0800 Subject: [PATCH 7/8] -n and -t are okay together --- assignment-client/src/AssignmentClientApp.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index 7c6fb50db2..cea952a806 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -120,11 +120,6 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt(); } if (parser.isSet(clientTypeOption)) { - if (numForks || minForks || maxForks) { - qCritical() << "don't use -t with forking mode."; - parser.showHelp(); - Q_UNREACHABLE(); - } requestAssignmentType = (Assignment::Type) parser.value(clientTypeOption).toInt(); } From b8322556a65a1c3cb2d15eb0de8354191f2d1b17 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Feb 2015 17:34:24 -0800 Subject: [PATCH 8/8] address code-review comments --- assignment-client/src/AssignmentClientApp.cpp | 7 +------ assignment-client/src/AssignmentClientMonitor.cpp | 6 +++--- libraries/networking/src/LimitedNodeList.h | 1 - 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index cea952a806..cfb77c8542 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -29,14 +29,13 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : setvbuf(stdout, NULL, _IOLBF, 0); # endif - + // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us # ifdef _WIN32 installNativeEventFilter(&ShutdownEventListener::getInstance()); # else ShutdownEventListener::getInstance(); # endif - setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); @@ -141,7 +140,6 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : walletUUID = parser.value(walletDestinationOption); } - QString assignmentServerHostname; if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); @@ -150,7 +148,6 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : assignmentServerHostname = parser.value(assignmentServerHostnameOption); } - // check for an overriden assignment server port quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) { @@ -177,12 +174,10 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : if (numForks || minForks || maxForks) { - // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us AssignmentClientMonitor monitor(numForks, minForks, maxForks, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); } else { - // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us AssignmentClient client(requestAssignmentType, assignmentPool, walletUUID, assignmentServerHostname, assignmentServerPort); exec(); diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index ffc402c04d..7517669d0b 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -43,8 +43,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen // create a NodeList so we can receive stats from children DependencyManager::registerInheritance(); auto addressManager = DependencyManager::set(); - auto nodeList = DependencyManager::set(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT, - DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT); + auto nodeList = DependencyManager::set(DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT); connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams); @@ -55,7 +54,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen spawnChildClient(); } - connect(&_checkSparesTimer, SIGNAL(timeout()), SLOT(checkSpares())); + connect(&_checkSparesTimer, &QTimer::timeout, this, &AssignmentClientMonitor::checkSpares); + _checkSparesTimer.start(NODE_SILENCE_THRESHOLD_MSECS * 3); } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 02234ee4f7..afc98de169 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -54,7 +54,6 @@ const QString ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY = "assignment-client const char DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME[] = "localhost"; const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_PORT = 40104; -const unsigned short DEFAULT_ASSIGNMENT_CLIENT_MONITOR_DTLS_PORT = 40105; class HifiSockAddr;