Skip to content

refactor: abstract connection/transport; and clearly separate qt remote obj and qt local into separate implementations#24

Closed
iurimatias wants to merge 1 commit intomasterfrom
ws/refactor_abstract_p1
Closed

refactor: abstract connection/transport; and clearly separate qt remote obj and qt local into separate implementations#24
iurimatias wants to merge 1 commit intomasterfrom
ws/refactor_abstract_p1

Conversation

@iurimatias
Copy link
Member

note: need #20 to go in first, and probably rebase again

Copilot AI review requested due to automatic review settings March 13, 2026 20:39
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the SDK’s module communication layer by introducing an abstract transport interface and splitting the Qt-based local vs remote implementations, so consumer/provider logic no longer directly depends on PluginRegistry or Qt Remote Objects APIs.

Changes:

  • Added LogosTransportHost / LogosTransportConnection abstractions plus a mode-based LogosTransportFactory.
  • Moved local and remote transport logic into cpp/implementations/qt_local and cpp/implementations/qt_remote.
  • Updated LogosAPIProvider and LogosAPIConsumer to use the transport layer; updated build/install packaging (CMake + Nix headers).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
nix/include.nix Installs new transport headers/sources and implementation files into the Nix header output.
cpp/logos_transport.h Introduces transport interfaces for publishing, requesting, releasing, and invoking methods.
cpp/logos_transport_factory.h Declares factory helpers to select transport based on LogosModeConfig.
cpp/logos_transport_factory.cpp Implements factory selection between local and remote transports.
cpp/implementations/qt_local/local_transport.h Declares local (PluginRegistry-based) transport implementation.
cpp/implementations/qt_local/local_transport.cpp Implements local publish/request/invoke using PluginRegistry + ModuleProxy.
cpp/implementations/qt_remote/remote_transport.h Declares remote (Qt Remote Objects-based) transport implementation.
cpp/implementations/qt_remote/remote_transport.cpp Implements remote registry host/node, acquireDynamic, and pending-call invocation.
cpp/logos_api_provider.h Switches provider storage from QRemoteObjectRegistryHost* to std::unique_ptr<LogosTransportHost>.
cpp/logos_api_provider.cpp Uses transport host to publish/unpublish the ModuleProxy instead of branching on mode.
cpp/logos_api_consumer.h Switches consumer storage from QRemoteObjectNode* to std::unique_ptr<LogosTransportConnection>.
cpp/logos_api_consumer.cpp Uses transport connection for request/reconnect/invoke/token calls.
cpp/CMakeLists.txt Adds new sources/headers to the static library and installs transport headers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

, m_registryUrl(QString("local:logos_%1").arg(module_to_talk_to))
, m_connected(false)
, m_token_manager(token_manager)
{
Comment on lines +19 to 21
m_transport = LogosTransportFactory::createConnection(m_registryUrl);
m_transport->connectToHost();
}
Comment on lines 69 to +82
QVariant LogosAPIConsumer::invokeRemoteMethod(const QString& authToken, const QString& objectName, const QString& methodName,
const QVariantList& args, Timeout timeout)
{
qDebug() << "LogosAPIConsumer: Calling invokeRemoteMethod:" << objectName << methodName << "args_count:" << args.size() << "timeout:" << timeout.ms;

// This method handles both ModuleProxy-wrapped modules (template_module, package_manager)
// and direct remote object calls for other modules
QObject* plugin = requestObject(objectName, timeout);
QObject* plugin = m_transport->requestObject(objectName, timeout.ms);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << objectName;
return QVariant();
}

ModuleProxy* moduleProxy = qobject_cast<ModuleProxy*>(plugin);
if (moduleProxy) {
QVariant result = moduleProxy->callRemoteMethod(authToken, methodName, args);
if (!LogosModeConfig::isLocal()) {
delete plugin;
}
return result;
}

if (LogosModeConfig::isLocal()) {
qWarning() << "LogosAPIConsumer: Local mode requires ModuleProxy-wrapped objects";
return QVariant();
}

// Remote mode: callRemoteMethod returns QRemoteObjectPendingCall, not QVariant
QRemoteObjectPendingCall pendingCall;
bool success = QMetaObject::invokeMethod(
plugin,
"callRemoteMethod",
Qt::DirectConnection,
Q_RETURN_ARG(QRemoteObjectPendingCall, pendingCall),
Q_ARG(QString, authToken),
Q_ARG(QString, methodName),
Q_ARG(QVariantList, args)
);

if (!success) {
qWarning() << "LogosAPIConsumer: Failed to invoke callRemoteMethod on replica for object:" << objectName;
delete plugin;
return QVariant();
}

// Wait for the result
pendingCall.waitForFinished(timeout.ms);
delete plugin;

if (!pendingCall.isFinished() || pendingCall.error() != QRemoteObjectPendingCall::NoError) {
qWarning() << "LogosAPIConsumer: Remote callRemoteMethod failed or timed out:" << pendingCall.error();
return QVariant();
}

return pendingCall.returnValue();
QVariant result = m_transport->callRemoteMethod(plugin, authToken, methodName, args, timeout.ms);
m_transport->releaseObject(plugin);
return result;
Comment on lines 143 to 150
bool LogosAPIConsumer::informModuleToken_module(const QString& authToken, const QString& originModule, const QString& moduleName, const QString& token)
{
qDebug() << "LogosAPIConsumer: Informing module token for module:" << moduleName << "with token:" << token;

QObject* plugin = requestObject(originModule, Timeout(20000));
QObject* plugin = m_transport->requestObject(originModule, 20000);
if (!plugin) {
qWarning() << "LogosAPIConsumer: Failed to acquire plugin/replica for object:" << originModule;
return false;
Comment on lines +62 to +74
/**
* @brief Acquire a handle to a named object from the host
* @param objectName The published name of the object
* @param timeoutMs Maximum time to wait for the object to become available
* @return QObject* handle, or nullptr on failure. Caller must use releaseObject() when done.
*/
virtual QObject* requestObject(const QString& objectName, int timeoutMs) = 0;

/**
* @brief Release a previously acquired object handle
* @param object The handle returned by requestObject()
*/
virtual void releaseObject(QObject* object) = 0;
…te obj and qt local into separate implementations
@iurimatias iurimatias force-pushed the ws/refactor_abstract_p1 branch from c3822c7 to b6ef910 Compare March 16, 2026 16:00
@iurimatias
Copy link
Member Author

closed in favour of #25

@iurimatias iurimatias closed this Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants