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
Closed
Conversation
There was a problem hiding this comment.
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/LogosTransportConnectionabstractions plus a mode-basedLogosTransportFactory. - Moved local and remote transport logic into
cpp/implementations/qt_localandcpp/implementations/qt_remote. - Updated
LogosAPIProviderandLogosAPIConsumerto 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
c3822c7 to
b6ef910
Compare
Member
Author
|
closed in favour of #25 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
note: need #20 to go in first, and probably rebase again