Add entity PPS per script configuration

This commit is contained in:
Ryan Huffman 2017-02-08 13:11:18 -08:00
parent 534d3c581c
commit f75eceda65
5 changed files with 106 additions and 2 deletions

View file

@ -30,7 +30,6 @@
int EntityScriptServer::_entitiesScriptEngineCount = 0;
EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssignment(message) {
_entityEditSender.setPacketsPerSecond(3000);
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
ResourceManager::init();
@ -101,6 +100,52 @@ void EntityScriptServer::handleEntityScriptGetStatusPacket(QSharedPointer<Receiv
}
}
void EntityScriptServer::handleSettings() {
auto nodeList = DependencyManager::get<NodeList>();
auto& domainHandler = nodeList->getDomainHandler();
const QJsonObject& settingsObject = domainHandler.getSettingsObject();
static const QString ENTITY_SCRIPT_SERVER_SETTINGS_KEY = "entity_script_server";
if (!settingsObject.contains(ENTITY_SCRIPT_SERVER_SETTINGS_KEY)) {
qWarning() << "Received settings from the domain-server with no entity_script_server section.";
return;
}
auto entityScriptServerSettings = settingsObject[ENTITY_SCRIPT_SERVER_SETTINGS_KEY].toObject();
static const QString MAX_ENTITY_PPS_OPTION = "max_total_entity_pps";
static const QString ENTITY_PPS_PER_SCRIPT = "entity_pps_per_script";
if (!entityScriptServerSettings.contains(MAX_ENTITY_PPS_OPTION) || !entityScriptServerSettings.contains(ENTITY_PPS_PER_SCRIPT)) {
qWarning() << "Received settings from the domain-server with no max_total_entity_pps or entity_pps_per_script properties.";
return;
}
_maxEntityPPS = std::max(0, entityScriptServerSettings[MAX_ENTITY_PPS_OPTION].toInt());
_entityPPSPerScript = std::max(0, entityScriptServerSettings[ENTITY_PPS_PER_SCRIPT].toInt());
qDebug() << QString("Received entity script server settings, Max Entity PPS: %1, Entity PPS Per Entity Script: %2")
.arg(_maxEntityPPS).arg(_entityPPSPerScript);
}
void EntityScriptServer::updateEntityPPS() {
int numRunningScripts = _entitiesScriptEngine->getNumRunningEntityScripts();
int pps;
if (std::numeric_limits<int>::max() / _entityPPSPerScript < numRunningScripts) {
qWarning() << QString("Integer multiplaction would overflow, clamping to maxint: %1 * %2").arg(numRunningScripts).arg(_entityPPSPerScript);
pps = std::numeric_limits<int>::max();
pps = std::min(_maxEntityPPS, pps);
} else {
pps = _entityPPSPerScript * numRunningScripts;
pps = std::min(_maxEntityPPS, pps);
}
_entityEditSender.setPacketsPerSecond(pps);
qDebug() << QString("Updating entity PPS to: %1 @ %2 PPS per script = %3 PPS").arg(numRunningScripts).arg(_entityPPSPerScript).arg(pps);
}
void EntityScriptServer::run() {
// make sure we request our script once the agent connects to the domain
auto nodeList = DependencyManager::get<NodeList>();
@ -115,6 +160,9 @@ void EntityScriptServer::run() {
connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init);
messagesThread->start();
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
connect(&domainHandler, &DomainHandler::settingsReceived, this, &EntityScriptServer::handleSettings);
// make sure we hear about connected nodes so we can grab an ATP script if a request is pending
connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &EntityScriptServer::nodeActivated);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptServer::nodeKilled);
@ -233,7 +281,9 @@ void EntityScriptServer::resetEntitiesScriptEngine() {
newEngine->runInThread();
DependencyManager::get<EntityScriptingInterface>()->setEntitiesScriptEngine(newEngine.data());
disconnect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, this, &EntityScriptServer::updateEntityPPS);
_entitiesScriptEngine.swap(newEngine);
connect(_entitiesScriptEngine.data(), &ScriptEngine::entityScriptDetailsUpdated, this, &EntityScriptServer::updateEntityPPS);
}

View file

@ -20,6 +20,9 @@
#include <ScriptEngine.h>
#include <ThreadedAssignment.h>
static const int DEFAULT_MAX_ENTITY_PPS = 9000;
static const int DEFAULT_ENTITY_PPS_PER_SCRIPT = 900;
class EntityScriptServer : public ThreadedAssignment {
Q_OBJECT
@ -42,6 +45,9 @@ private slots:
void handleReloadEntityServerScriptPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void handleEntityScriptGetStatusPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
void handleSettings();
void updateEntityPPS();
private:
void negotiateAudioFormat();
void selectAudioFormat(const QString& selectedCodecName);
@ -62,6 +68,9 @@ private:
EntityEditPacketSender _entityEditSender;
EntityTreeHeadlessViewer _entityViewer;
int _maxEntityPPS { DEFAULT_MAX_ENTITY_PPS };
int _entityPPSPerScript { DEFAULT_ENTITY_PPS_PER_SCRIPT };
QString _selectedCodecName;
CodecPluginPointer _codec;
Encoder* _encoder { nullptr };

View file

@ -390,7 +390,7 @@
{
"name": "maximum_user_capacity_redirect_location",
"label": "Redirect to Location on Maximum Capacity",
"help": "Is there another domain, you'd like to redirect clients to when the maximum number of avatars are connected.",
"help": "The location to redirect users to when the maximum number of avatars are connected.",
"placeholder": "",
"default": "",
"advanced": false
@ -1034,6 +1034,29 @@
}
]
},
{
"name": "entity_script_server",
"label": "Entity Script Server (ESS)",
"assignment-types": [5],
"settings": [
{
"name": "entity_pps_per_script",
"label": "Entity PPS per script",
"help": "The number of packets per second (PPS) that can be sent to the entity server for each server entity script. This contributes to a total overall amount.<br/>Example: 1000 PPS with 5 entites gives a total PPS of 5000 that is shared among the entity scripts. A single could use 4000 PPS, leaving 1000 for the rest, for example.",
"default": 900,
"type": "int",
"advanced": true
},
{
"name": "max_total_entity_pps",
"label": "Maximum Total Entity PPS",
"help": "The maximum total packets per seconds (PPS) that can be sent to the entity server.<br/>Example: 5 scripts @ 1000 PPS per script = 5000 total PPS. A maximum total PPS of 4000 would cap this 5000 total PPS to 4000.",
"default": 9000,
"type": "int",
"advanced": true
}
]
},
{
"name": "avatars",
"label": "Avatars",

View file

@ -1393,6 +1393,16 @@ void ScriptEngine::forwardHandlerCall(const EntityItemID& entityID, const QStrin
}
}
int ScriptEngine::getNumRunningEntityScripts() const {
int sum = 0;
for (auto& st : _entityScripts) {
if (st.status == RUNNING) {
++sum;
}
}
return sum;
}
bool ScriptEngine::getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const {
auto it = _entityScripts.constFind(entityID);
if (it == _entityScripts.constEnd()) {
@ -1456,6 +1466,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
newDetails.status = ERROR_LOADING_SCRIPT;
newDetails.errorInfo = "Failed to load script";
_entityScripts[entityID] = newDetails;
emit entityScriptDetailsUpdated();
return;
}
@ -1467,6 +1478,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
newDetails.status = ERROR_RUNNING_SCRIPT;
newDetails.errorInfo = "Bad syntax";
_entityScripts[entityID] = newDetails;
emit entityScriptDetailsUpdated();
return; // done processing script
}
@ -1497,6 +1509,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
newDetails.status = ERROR_RUNNING_SCRIPT;
newDetails.errorInfo = exceptionMessage;
_entityScripts[entityID] = newDetails;
emit entityScriptDetailsUpdated();
return;
}
@ -1523,6 +1536,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
newDetails.status = ERROR_RUNNING_SCRIPT;
newDetails.errorInfo = "Could not find constructor";
_entityScripts[entityID] = newDetails;
emit entityScriptDetailsUpdated();
return; // done processing script
}
@ -1544,6 +1558,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
newDetails.lastModified = lastModified;
newDetails.definingSandboxURL = sandboxURL;
_entityScripts[entityID] = newDetails;
emit entityScriptDetailsUpdated();
if (isURL) {
setParentURL("");
@ -1575,6 +1590,7 @@ void ScriptEngine::unloadEntityScript(const EntityItemID& entityID) {
}
_entityScripts.remove(entityID);
stopAllTimersForEntityScript(entityID);
emit entityScriptDetailsUpdated();
}
}
@ -1596,6 +1612,7 @@ void ScriptEngine::unloadAllEntityScripts() {
}
}
_entityScripts.clear();
emit entityScriptDetailsUpdated();
#ifdef DEBUG_ENGINE_STATE
qCDebug(scriptengine) << "---- CURRENT STATE OF ENGINE: --------------------------";

View file

@ -199,6 +199,7 @@ public:
void scriptWarningMessage(const QString& message);
void scriptInfoMessage(const QString& message);
int getNumRunningEntityScripts() const;
bool getEntityScriptDetails(const EntityItemID& entityID, EntityScriptDetails &details) const;
public slots:
@ -222,6 +223,10 @@ signals:
void reloadScript(const QString& scriptName, bool isUserLoaded);
void doneRunning();
// Emitted when an entity script is added or removed, or when the status of an entity
// script is updated (goes from RUNNING to ERROR_RUNNING_SCRIPT, for example)
void entityScriptDetailsUpdated();
protected:
void init();