Skip to content

Commit 081b544

Browse files
committed
Fallback to first running instance, if session has wrong non existing instance
1 parent 45fa6c7 commit 081b544

File tree

2 files changed

+89
-78
lines changed

2 files changed

+89
-78
lines changed

assets/webconfig/js/hyperion.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -330,23 +330,24 @@ function requestInstanceSwitch(instance) {
330330
sendToHyperion("instance", "switchTo", {}, Number(instance));
331331
}
332332

333-
function requestServerInfo(instance) {
334-
let data = {
335-
subscribe: [
336-
"components-update",
337-
"priorities-update",
338-
"imageToLedMapping-update",
339-
"adjustment-update",
340-
"videomode-update",
341-
"effects-update",
342-
"settings-update",
343-
"instance-update",
344-
"event-update"
345-
]
346-
};
347-
348-
sendToHyperion("serverinfo", "getInfo", data, Number(instance));
349-
return Promise.resolve();
333+
function requestServerInfo(instance = null) {
334+
const subscriptions = [
335+
"components-update",
336+
"priorities-update",
337+
"imageToLedMapping-update",
338+
"adjustment-update",
339+
"videomode-update",
340+
"effects-update",
341+
"settings-update",
342+
"instance-update",
343+
"event-update"
344+
];
345+
346+
const data = { subscribe: subscriptions };
347+
348+
const targetInstance = instance !== null ? Number(instance) : null;
349+
350+
return sendToHyperion("serverinfo", "getInfo", data, targetInstance);
350351
}
351352

352353
function requestSysInfo() {

libsrc/api/JsonAPI.cpp

Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -294,121 +294,119 @@ void JsonAPI::handleInstanceCommand(const JsonApiCommand& cmd, const QJsonObject
294294
else
295295
{
296296
// If no instance element is given use the one that was switched to before
297-
if (instanceElement.isUndefined() && _currInstanceIndex != NO_INSTANCE_ID)
297+
if (_currInstanceIndex != NO_INSTANCE_ID)
298298
{
299299
instances.append(_currInstanceIndex);
300300
}
301301
else
302302
{
303303
//If no instance was given nor one was switched to before, use first running instance (backward compatability)
304-
if (_currInstanceIndex == NO_INSTANCE_ID)
304+
quint8 const firstRunningInstanceID = _instanceManager->getFirstRunningInstanceIdx();
305+
if (firstRunningInstanceID == NO_INSTANCE_ID)
305306
{
306-
quint8 const firstRunningInstanceID = _instanceManager->getFirstRunningInstanceIdx();
307-
if (firstRunningInstanceID != NO_INSTANCE_ID)
308-
{
309-
instances.append(firstRunningInstanceID);
310-
Debug(_log,"No instance ID(s) provided; applying API request to first running instance [%u]", firstRunningInstanceID);
311-
if (!handleInstanceSwitch(firstRunningInstanceID))
312-
{
313-
QString errorText = QString("Error switching to first running instance: [%1] to process API request").arg(firstRunningInstanceID);
314-
Error(_log, "%s", QSTRING_CSTR(errorText));
315-
sendErrorReply(errorText, cmd);
316-
return;
317-
}
318-
}
319-
else
320-
{
321-
QString errorText {"No instance(s) IDs provided and no running instance available applying the API request to"};
322-
Error(_log, "%s", QSTRING_CSTR(errorText));
323-
sendErrorReply(errorText, cmd);
324-
return;
325-
}
307+
QString errorText {"No instance(s) IDs provided and no running instance available applying the API request to"};
308+
Error(_log, "%s", QSTRING_CSTR(errorText));
309+
sendErrorReply(errorText, cmd);
310+
return;
311+
}
312+
313+
instances.append(firstRunningInstanceID);
314+
Debug(_log,"No instance ID(s) provided; applying API request to first running instance [%u]", firstRunningInstanceID);
315+
316+
if (!handleInstanceSwitch(firstRunningInstanceID))
317+
{
318+
QString errorText = QString("Error switching to first running instance: [%1] to process API request").arg(firstRunningInstanceID);
319+
Error(_log, "%s", QSTRING_CSTR(errorText));
320+
sendErrorReply(errorText, cmd);
321+
return;
326322
}
327323
}
328324
}
329325

330-
InstanceCmd::MustRun const isRunningInstanceRequired = cmd.getInstanceMustRun();
331-
QSet const runningInstanceIds = _instanceManager->getRunningInstanceIdx();
326+
InstanceCmd::MustRun const mustRun = cmd.getInstanceMustRun();
327+
QSet<quint8> const configuredInstanceIds = _instanceManager->getInstanceIds();
328+
QSet<quint8> const runningInstanceIds = _instanceManager->getRunningInstanceIdx();
332329
QSet<quint8> instanceIds;
333330
QStringList errorDetails;
331+
QStringList errorDetailsInvalidInstances;
334332

335333
// Determine instance IDs, if empty array provided apply command to all instances
336334
if (instances.isEmpty())
337335
{
338-
instanceIds = (isRunningInstanceRequired == InstanceCmd::MustRun_Yes) ? runningInstanceIds : _instanceManager->getInstanceIds();
336+
instanceIds = (mustRun == InstanceCmd::MustRun_Yes) ? runningInstanceIds : _instanceManager->getInstanceIds();
339337
}
340338
else
341339
{
342-
QSet<quint8> const configuredInstanceIds = _instanceManager->getInstanceIds();
343-
344340
//Resolve instances provided and test, if they need to be running
345341
for (const auto &instance : std::as_const(instances))
346342
{
347343
quint8 const instanceId = static_cast<quint8>(instance.toInt());
348344
if (!configuredInstanceIds.contains(instanceId))
349345
{
350-
errorDetails.append(QString("Not a valid instance id: [%1]").arg(instanceId));
346+
//Do not store in errorDetails, as command could be one working with and without instance
347+
errorDetailsInvalidInstances.append(QString("Not a valid instance id: [%1]").arg(instanceId));
351348
continue;
352349
}
353350

354-
if (isRunningInstanceRequired == InstanceCmd::MustRun_Yes && !runningInstanceIds.contains(instanceId))
351+
if (mustRun == InstanceCmd::MustRun_Yes && !runningInstanceIds.contains(instanceId))
355352
{
356-
errorDetails.append(QString("Instance [%1] is not running, but the (sub-) command requires a running instance.").arg(instance.toVariant().toString()));
357-
}
358-
else
359-
{
360-
instanceIds.insert(instanceId);
353+
errorDetails.append(QString("Instance [%1] is not running, but the (sub-) command requires a running instance.")
354+
.arg(instance.toVariant().toString()));
355+
continue;
361356
}
357+
358+
instanceIds.insert(instanceId);
362359
}
363360
}
364361

365362
// Handle cases where no instances are found
366363
if (instanceIds.isEmpty())
367364
{
368-
if (errorDetails.isEmpty() && (cmd.getInstanceCmdType() == InstanceCmd::No_or_Single || cmd.getInstanceCmdType() == InstanceCmd::No_or_Multi) )
365+
if (errorDetails.isEmpty() &&
366+
(cmd.getInstanceCmdType() == InstanceCmd::No_or_Single || cmd.getInstanceCmdType() == InstanceCmd::No_or_Multi) )
369367
{
370368
handleCommand(cmd, message);
371369
return;
372370
}
371+
372+
errorDetails.append(errorDetailsInvalidInstances);
373373
errorDetails.append("No valid instance(s) provided");
374-
}
375-
else
376-
{
377-
// Check if multiple instances are allowed
378-
if (instanceIds.size() > 1 && cmd.getInstanceCmdType() != InstanceCmd::Multi)
379-
{
380-
errorDetails.append("Command does not support multiple instances");
381-
}
374+
375+
sendErrorReply("Errors for instance(s) given", errorDetails, cmd);
376+
return;
382377
}
383378

384-
// If there are errors, send a response and exit
385-
if ( !errorDetails.isEmpty() )
379+
// Check if multiple instances are allowed
380+
if (instanceIds.size() > 1 && cmd.getInstanceCmdType() != InstanceCmd::Multi)
386381
{
382+
errorDetails.append("Command does not support multiple instances");
387383
sendErrorReply("Errors for instance(s) given", errorDetails, cmd);
388384
return;
389385
}
390386

391387
// Execute the command for each valid instance
392-
quint8 const currentInstance = _currInstanceIndex;
388+
quint8 const previousInstance = _currInstanceIndex;
389+
393390
for (const auto &instanceId : std::as_const(instanceIds))
394391
{
395-
if (isRunningInstanceRequired == InstanceCmd::MustRun_Yes || _currInstanceIndex == NO_INSTANCE_ID)
392+
bool isCorrectInstance = true;
393+
394+
if (mustRun == InstanceCmd::MustRun_Yes || _currInstanceIndex == NO_INSTANCE_ID)
396395
{
397-
if (handleInstanceSwitch(instanceId))
398-
{
399-
handleCommand(cmd, message);
400-
}
396+
isCorrectInstance = handleInstanceSwitch(instanceId);
401397
}
402-
else
398+
399+
if (isCorrectInstance)
403400
{
404401
handleCommand(cmd, message);
405402
}
406403
}
407404

408405
//Switch back to current instance, if command was executed against multiple instances
409-
if (currentInstance != _currInstanceIndex && (cmd.getInstanceCmdType() == InstanceCmd::Multi || cmd.getInstanceCmdType() == InstanceCmd::No_or_Multi))
406+
if (previousInstance != _currInstanceIndex &&
407+
(cmd.getInstanceCmdType() == InstanceCmd::Multi || cmd.getInstanceCmdType() == InstanceCmd::No_or_Multi))
410408
{
411-
handleInstanceSwitch(currentInstance);
409+
handleInstanceSwitch(previousInstance);
412410
}
413411
}
414412

@@ -1529,7 +1527,7 @@ void JsonAPI::handleInstanceCommand(const QJsonObject &message, const JsonApiCom
15291527

15301528
QJsonValue const instanceValue = message["instance"];
15311529

1532-
const quint8 instanceID = static_cast<quint8>(instanceValue.toInt());
1530+
quint8 instanceID = static_cast<quint8>(instanceValue.toInt());
15331531
if(cmd.subCommand != SubCommand::CreateInstance)
15341532
{
15351533
QString errorText;
@@ -1540,12 +1538,24 @@ void JsonAPI::handleInstanceCommand(const QJsonObject &message, const JsonApiCom
15401538
} else if (!_instanceManager->doesInstanceExist(instanceID))
15411539
{
15421540
errorText = QString("Hyperion instance [%1] does not exist.").arg(instanceID);
1543-
}
1541+
Error(_log, "%s", QSTRING_CSTR(errorText));
15441542

1545-
if (!errorText.isEmpty())
1546-
{
1547-
sendErrorReply( errorText, cmd);
1548-
return;
1543+
if (cmd.subCommand != SubCommand::SwitchTo)
1544+
{
1545+
sendErrorReply(errorText, cmd);
1546+
return;
1547+
}
1548+
1549+
//Use first running instance (backward compatability)
1550+
quint8 const firstRunningInstanceID = _instanceManager->getFirstRunningInstanceIdx();
1551+
if (firstRunningInstanceID == NO_INSTANCE_ID)
1552+
{
1553+
sendErrorReply(errorText, cmd);
1554+
return;
1555+
}
1556+
1557+
errorDetails.append(QString("Hyperion instance [%1] does not exist, using first running instance [%2]").arg(instanceID).arg(firstRunningInstanceID));
1558+
instanceID = firstRunningInstanceID;
15491559
}
15501560
}
15511561

@@ -1557,7 +1567,7 @@ void JsonAPI::handleInstanceCommand(const QJsonObject &message, const JsonApiCom
15571567
if (handleInstanceSwitch(instanceID))
15581568
{
15591569
QJsonObject const response { { "instance", instanceID } };
1560-
sendSuccessDataReply(response, cmd);
1570+
sendSuccessDataReplyWithError(response, cmd, errorDetails);
15611571
}
15621572
else
15631573
{

0 commit comments

Comments
 (0)