First draft for entity script server log streaming

This commit is contained in:
Atlante45 2017-01-31 16:09:56 -08:00
parent 74f10a1e7f
commit fcb74bce10
7 changed files with 155 additions and 12 deletions

View file

@ -27,6 +27,7 @@ public:
QUuid walletUUID, QString assignmentServerHostname, quint16 assignmentServerPort,
quint16 assignmentMonitorPort);
~AssignmentClient();
private slots:
void sendAssignmentRequest();
void assignmentCompleted();

View file

@ -27,9 +27,30 @@
#include "ClientServerUtils.h"
#include "../entities/AssignmentParentFinder.h"
#include <LogHandler.h>
#include <mutex>
using Mutex = std::mutex;
using Lock = std::lock_guard<Mutex>;
static std::mutex logBufferMutex;
static std::string logBuffer;
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
auto logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message);
if (!logMessage.isEmpty()) {
Lock lock(logBufferMutex);
logBuffer.append(logMessage.toStdString() + '\n');
}
}
int EntityScriptServer::_entitiesScriptEngineCount = 0;
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) {
qInstallMessageHandler(messageHandler);
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
ResourceManager::init();
@ -57,6 +78,18 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
static const int LOG_INTERVAL = MSECS_PER_SECOND / 50;
auto timer = new QTimer(this);
timer->setTimerType(Qt::PreciseTimer);
timer->setInterval(LOG_INTERVAL);
connect(timer, &QTimer::timeout, this, &EntityScriptServer::pushLogs);
timer->start();
}
EntityScriptServer::~EntityScriptServer() {
qInstallMessageHandler(LogHandler::verboseMessageHandler);
}
static const QString ENTITY_SCRIPT_SERVER_LOGGING_NAME = "entity-script-server";
@ -146,6 +179,60 @@ void EntityScriptServer::updateEntityPPS() {
qDebug() << QString("Updating entity PPS to: %1 @ %2 PPS per script = %3 PPS").arg(numRunningScripts).arg(_entityPPSPerScript).arg(pps);
}
void EntityScriptServer::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
// These are temporary checks until we can ensure that nodes eventually disconnect if the Domain Server stops telling them
// about each other.
if (senderNode->getCanRez() || senderNode->getCanRezTmp()) {
bool enable = false;
message->readPrimitive(&enable);
qInfo() << "======== Got log packet:" << enable;
if (enable) {
_logListeners.insert(senderNode->getUUID());
} else {
_logListeners.erase(senderNode->getUUID());
}
}
}
void EntityScriptServer::pushLogs() {
std::string buffer;
{
Lock lock(logBufferMutex);
std::swap(logBuffer, buffer);
}
if (buffer.empty()) {
return;
}
if (_logListeners.empty()) {
return;
}
auto packet = NLPacket::create(PacketType::EntityServerScriptLog, buffer.size(), true);
packet->write(buffer.data(), buffer.size());
auto nodeList = DependencyManager::get<NodeList>();
auto last = --std::end(_logListeners);
for (auto it = std::begin(_logListeners); it != last; ++it) {
auto node = nodeList->nodeWithUUID(*it);
if (node && node->getActiveSocket()) {
auto copy = NLPacket::createCopy(*packet);
nodeList->sendPacket(std::move(copy), *node);
} else {
qWarning() << "Node not found";
}
}
auto node = nodeList->nodeWithUUID(*last);
if (node && node->getActiveSocket()) {
nodeList->sendPacket(std::move(packet), *node);
} else {
qWarning() << "Node not found";
}
}
void EntityScriptServer::run() {
// make sure we request our script once the agent connects to the domain
auto nodeList = DependencyManager::get<NodeList>();
@ -347,15 +434,27 @@ void EntityScriptServer::checkAndCallPreload(const EntityItemID& entityID, const
}
void EntityScriptServer::nodeKilled(SharedNodePointer killedNode) {
if (!_shuttingDown && killedNode->getType() == NodeType::EntityServer) {
if (_entitiesScriptEngine) {
_entitiesScriptEngine->unloadAllEntityScripts();
_entitiesScriptEngine->stop();
switch (killedNode->getType()) {
case NodeType::EntityServer: {
if (!_shuttingDown) {
if (_entitiesScriptEngine) {
_entitiesScriptEngine->unloadAllEntityScripts();
_entitiesScriptEngine->stop();
}
resetEntitiesScriptEngine();
_entityViewer.clear();
}
break;
}
resetEntitiesScriptEngine();
_entityViewer.clear();
case NodeType::Agent: {
_logListeners.erase(killedNode->getUUID());
break;
}
default:
// Do nothing
break;
}
}

View file

@ -12,7 +12,10 @@
#ifndef hifi_EntityScriptServer_h
#define hifi_EntityScriptServer_h
#include <set>
#include <QtCore/QObject>
#include <QtCore/QUuid>
#include <EntityEditPacketSender.h>
#include <EntityTreeHeadlessViewer.h>
@ -28,6 +31,7 @@ class EntityScriptServer : public ThreadedAssignment {
public:
EntityScriptServer(ReceivedMessage& message);
~EntityScriptServer();
virtual void aboutToFinish() override;
@ -48,6 +52,10 @@ private slots:
void handleSettings();
void updateEntityPPS();
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void pushLogs();
private:
void negotiateAudioFormat();
void selectAudioFormat(const QString& selectedCodecName);
@ -71,6 +79,8 @@ private:
int _maxEntityPPS { DEFAULT_MAX_ENTITY_PPS };
int _entityPPSPerScript { DEFAULT_ENTITY_PPS_PER_SCRIPT };
std::set<QUuid> _logListeners;
QString _selectedCodecName;
CodecPluginPointer _codec;
Encoder* _encoder { nullptr };

View file

@ -46,6 +46,9 @@ int qTextBlockMeta = qRegisterMetaType<QTextBlock>("QTextBlock");
LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : QDialog(parent, Qt::Window) {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
_logger = logger;
setWindowTitle("Log");
setAttribute(Qt::WA_DeleteOnClose);
@ -64,7 +67,7 @@ LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : QDialog
move(screen.center() - rect().center());
setMinimumWidth(MINIMAL_WIDTH);
connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
//connect(_logger, SIGNAL(logReceived(QString)), this, SLOT(appendLogLine(QString)), Qt::QueuedConnection);
}
LogDialog::~LogDialog() {
@ -97,7 +100,8 @@ void LogDialog::initControls() {
_extraDebuggingBox->setCheckState(Qt::Checked);
}
_extraDebuggingBox->show();
connect(_extraDebuggingBox, SIGNAL(stateChanged(int)), SLOT(handleExtraDebuggingCheckbox(int)));
//connect(_extraDebuggingBox, SIGNAL(stateChanged(int)), SLOT(handleExtraDebuggingCheckbox(int)));
connect(_extraDebuggingBox, &QCheckBox::stateChanged, this, &LogDialog::enableToEntityServerScriptLog);
_revealLogButton = new QPushButton("Reveal log file", this);
// set object name for css styling
@ -156,6 +160,31 @@ void LogDialog::showLogData() {
_logTextBox->ensureCursorVisible();
}
void LogDialog::enableToEntityServerScriptLog(bool enable) {
qDebug() << Q_FUNC_INFO << enable;
auto nodeList = DependencyManager::get<NodeList>();
if (auto node = nodeList->soloNodeOfType(NodeType::EntityScriptServer)) {
auto packet = NLPacket::create(PacketType::EntityServerScriptLog, sizeof(bool), true);
packet->writePrimitive(enable);
nodeList->sendPacket(std::move(packet), *node);
if (enable) {
appendLogLine("====================== Subscribded to the Entity Script Server's log ======================");
} else {
appendLogLine("==================== Unsubscribded from the Entity Script Server's log ====================");
}
} else {
qWarning() << "Entity Script Server not found";
}
}
void LogDialog::handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
auto lines = QString::fromUtf8(message->readAll());
QMetaObject::invokeMethod(this, "appendLogLine", Q_ARG(QString, lines));
}
KeywordHighlighter::KeywordHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent), keywordFormat() {
keywordFormat.setForeground(QColor(HIGHLIGHT_COLOR));
}

View file

@ -53,6 +53,9 @@ private slots:
void handleExtraDebuggingCheckbox(const int);
void handleSearchTextChanged(const QString);
void enableToEntityServerScriptLog(bool enable);
void handleEntityServerScriptLogPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
protected:
void resizeEvent(QResizeEvent*) override;
void showEvent(QShowEvent*) override;

View file

@ -162,4 +162,4 @@ void EntityScriptClient::forceFailureOfPendingRequests(SharedNodePointer node) {
messageMapIt->second.clear();
}
}
}
}

View file

@ -111,7 +111,8 @@ public:
EntityScriptGetStatusReply,
ReloadEntityServerScript,
EntityPhysics,
LAST_PACKET_TYPE = EntityPhysics
EntityServerScriptLog,
LAST_PACKET_TYPE = EntityServerScriptLog
};
};