refactor: invert dependency between Message and Connection (#457)

This reorganizes the layers of abstraction in the sense how `Message` depends on `Connection` and vice versa. Now, `Message` has a link to the `Connection`. This replaces the shortcut link to the low-level `SdBus` interface that the `Message` kept. The interactions from `Message` now go through `Connection` which forwards them to `SdBus`. `Connection` is now a sole owner of the low-level `SdBus` interface. This allows for future changes around `SdBus` (e.g. a change from virtual functions back to non-virtual functions) without affecting the rest of the library. `Proxy`s and `Object`s can now send messages directly without having to go through `Connection`. The `Connection` no more depends on `Message` business-logic methods; it serves only as a factory for messages.

The flow for creating messages: `Proxy`/`Object` -> `Connection` -> `SdBus`
The flow for sending messages: (`Proxy`/`Object` ->) `Message` -> `Connection` -> `SdBus`

This also better reflects how dependencies are managed in the underlying sd-bus library.

Additionally, `getSdBusInterface()` methods are removed which was anyway planned, and improves the design by "Tell, don't ask" principle.

This refactoring is the necessary enabler for other upcoming improvements (regarding sending long messages, or creds refactoring, for example).
This commit is contained in:
Stanislav Angelovič
2024-10-02 21:22:02 +02:00
committed by GitHub
parent 1b7acaa735
commit 107c6a1a97
16 changed files with 234 additions and 177 deletions

View File

@@ -84,12 +84,12 @@ Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
// This proxy is meant to be created, used for simple synchronous D-Bus call(s) and then dismissed.
}
MethodCall Proxy::createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName)
MethodCall Proxy::createMethodCall(const InterfaceName& interfaceName, const MethodName& methodName) const
{
return connection_->createMethodCall(destination_, objectPath_, interfaceName, methodName);
}
MethodCall Proxy::createMethodCall(const char* interfaceName, const char* methodName)
MethodCall Proxy::createMethodCall(const char* interfaceName, const char* methodName) const
{
return connection_->createMethodCall(destination_.c_str(), objectPath_.c_str(), interfaceName, methodName);
}
@@ -103,7 +103,7 @@ MethodReply Proxy::callMethod(const MethodCall& message, uint64_t timeout)
{
SDBUS_THROW_ERROR_IF(!message.isValid(), "Invalid method call message provided", EINVAL);
return connection_->callMethod(message, timeout);
return message.send(timeout);
}
PendingAsyncCall Proxy::callMethodAsync(const MethodCall& message, async_reply_handler asyncReplyCallback)
@@ -124,11 +124,7 @@ PendingAsyncCall Proxy::callMethodAsync(const MethodCall& message, async_reply_h
, .proxy = *this
, .floating = false });
asyncCallInfo->slot = connection_->callMethod( message
, (void*)&Proxy::sdbus_async_reply_handler
, asyncCallInfo.get()
, timeout
, return_slot );
asyncCallInfo->slot = message.send((void*)&Proxy::sdbus_async_reply_handler, asyncCallInfo.get(), timeout, return_slot);
auto asyncCallInfoWeakPtr = std::weak_ptr{asyncCallInfo};
@@ -145,11 +141,7 @@ Slot Proxy::callMethodAsync(const MethodCall& message, async_reply_handler async
, .proxy = *this
, .floating = true });
asyncCallInfo->slot = connection_->callMethod( message
, (void*)&Proxy::sdbus_async_reply_handler
, asyncCallInfo.get()
, timeout
, return_slot );
asyncCallInfo->slot = message.send((void*)&Proxy::sdbus_async_reply_handler, asyncCallInfo.get(), timeout, return_slot);
return {asyncCallInfo.release(), [](void *ptr){ delete static_cast<AsyncCallInfo*>(ptr); }};
}
@@ -259,7 +251,7 @@ int Proxy::sdbus_async_reply_handler(sd_bus_message *sdbusMessage, void *userDat
proxy.floatingAsyncCallSlots_.erase(asyncCallInfo);
};
auto message = Message::Factory::create<MethodReply>(sdbusMessage, &proxy.connection_->getSdBusInterface());
auto message = Message::Factory::create<MethodReply>(sdbusMessage, proxy.connection_.get());
auto ok = invokeHandlerAndCatchErrors([&]
{
@@ -284,8 +276,7 @@ int Proxy::sdbus_signal_handler(sd_bus_message *sdbusMessage, void *userData, sd
assert(signalInfo != nullptr);
assert(signalInfo->callback);
// TODO: Hide Message factory invocation under Connection API (tell, don't ask principle), then we can remove getSdBusInterface()
auto message = Message::Factory::create<Signal>(sdbusMessage, &signalInfo->proxy.connection_->getSdBusInterface());
auto message = Message::Factory::create<Signal>(sdbusMessage, signalInfo->proxy.connection_.get());
auto ok = invokeHandlerAndCatchErrors([&](){ signalInfo->callback(std::move(message)); }, retError);