feat: add createLightWeightProxy overload for convenience (#474)

This commit is contained in:
Stanislav Angelovič
2025-01-08 13:55:38 +01:00
committed by GitHub
parent fafe8487ff
commit 48ea775531
4 changed files with 37 additions and 9 deletions

View File

@ -473,11 +473,11 @@ On the **client** side we likewise need a connection -- just that unlike on the
* when created **without** `dont_run_event_loop_thread_t` tag, the proxy **will start** a dedicated event loop thread on that connection;
* or, when created **with** `dont_run_event_loop_thread_t` tag, the proxy will start **no** event loop thread on that connection.
* Or we don't care about connnections at all (proxy factory overloads with no connection parameter). Under the hood, the proxy creates its own connection, to either the session bus (when in a user context) or the system bus otherwise. Additionally:
* Or we don't care about connections at all (proxy factory overloads with no connection parameter). Under the hood, the proxy creates its own connection, to either the session bus (when in a user context) or the system bus otherwise. Additionally:
* when created **without** `dont_run_event_loop_thread_t` tag, the proxy **will start** a dedicated event loop thread on that connection;
* or, when created **with** `dont_run_event_loop_thread_t` tag, the proxy will start **no** event loop thread on that connection.
A proxy needs an event loop if it's a "**long-lived**" proxy that listens on incoming messages like signals, async call replies, atc. Sharing one connection with its one event loop is more scalable. Starting a dedicated event loop in a proxy is simpler from API perspective, but comes at a performance and resource cost for each proxy creation/destruction, and it hurts scalability. A simple and scalable option are "**short-lived, light-weight**" proxies. Quite a typical use case is that we occasionally need to carry out one or a few D-Bus calls and that's it. We may create a proxy, do the calls, and let go of proxy. Such a light-weight proxy is created when `dont_run_event_loop_thread_t` tag is passed to the proxy factory. Such a proxy **does not spawn** an event loop thread. It only support synchronous D-Bus calls (no signals, no async calls...), and is meant to be created, used right away, and then destroyed immediately.
A proxy needs an event loop if it's a "**long-lived**" proxy that listens on incoming messages like signals, async call replies, atc. Sharing one connection with its one event loop is more scalable. Starting a dedicated event loop in a proxy is simpler from API perspective, but comes at a performance and resource cost for each proxy creation/destruction, and it hurts scalability. A simple and scalable option are "**short-lived, light-weight**" proxies. Quite a typical use case is that we occasionally need to carry out one or a few D-Bus calls and that's it. We may create a proxy, do the calls, and let go of proxy. Such a light-weight proxy is created when `dont_run_event_loop_thread_t` tag is passed to the proxy factory (or with `createLightWeightProxy()`). Such a proxy **does not spawn** an event loop thread. It only support synchronous D-Bus calls (no signals, no async calls...), and is meant to be created, used right away, and then destroyed immediately.
#### Stopping internal I/O event loops graciously

View File

@ -385,7 +385,7 @@ namespace sdbus {
* callMethod() function overload, which does not block the bus connection, or do the synchronous
* call from another Proxy instance created just before the call and then destroyed (which is
* anyway quite a typical approach in D-Bus implementations). Such proxy instance must have
* its own bus connection. So-called light-weight proxies (ones created with `dont_run_event_loop_thread`
* its own bus connection. So-called light-weight proxies (ones running without an event loop thread)
* tag are designed for exactly that purpose.
*
* The default D-Bus method call timeout is used. See IConnection::getMethodCallTimeout().
@ -416,7 +416,7 @@ namespace sdbus {
* callMethod() function overload, which does not block the bus connection, or do the synchronous
* call from another Proxy instance created just before the call and then destroyed (which is
* anyway quite a typical approach in D-Bus implementations). Such proxy instance must have
* its own bus connection. So-called light-weight proxies (ones created with `dont_run_event_loop_thread`
* its own bus connection. So-called light-weight proxies (ones running without an event loop thread)
* tag are designed for exactly that purpose.
*
* If timeout is zero, the default D-Bus method call timeout is used. See IConnection::getMethodCallTimeout().
@ -889,7 +889,7 @@ namespace sdbus {
, ObjectPath objectPath );
/*!
* @brief Creates a proxy object for a specific remote D-Bus object
* @brief Creates a light-weight proxy object for a specific remote D-Bus object
*
* @param[in] connection D-Bus connection to be used by the proxy object
* @param[in] destination Bus name that provides the remote D-Bus object
@ -916,6 +916,15 @@ namespace sdbus {
, ObjectPath objectPath
, dont_run_event_loop_thread_t );
/*!
* @brief Creates a light-weight proxy object for a specific remote D-Bus object
*
* Does the same thing as createProxy(std::unique_ptr<sdbus::IConnection>&&, ServiceName, ObjectPath, dont_run_event_loop_thread_t);
*/
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createLightWeightProxy( std::unique_ptr<sdbus::IConnection>&& connection
, ServiceName destination
, ObjectPath objectPath );
/*!
* @brief Creates a proxy object for a specific remote D-Bus object
*
@ -937,7 +946,7 @@ namespace sdbus {
, ObjectPath objectPath );
/*!
* @brief Creates a proxy object for a specific remote D-Bus object
* @brief Creates a light-weight proxy object for a specific remote D-Bus object
*
* @param[in] destination Bus name that provides the remote D-Bus object
* @param[in] objectPath Path of the remote D-Bus object
@ -958,6 +967,13 @@ namespace sdbus {
, ObjectPath objectPath
, dont_run_event_loop_thread_t );
/*!
* @brief Creates a light-weight proxy object for a specific remote D-Bus object
*
* Does the same thing as createProxy(ServiceName, ObjectPath, dont_run_event_loop_thread_t);
*/
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createLightWeightProxy(ServiceName destination, ObjectPath objectPath);
}
#include <sdbus-c++/ConvenienceApiClasses.inl>

View File

@ -400,6 +400,13 @@ std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<IConnection>&& conne
, dont_run_event_loop_thread );
}
std::unique_ptr<sdbus::IProxy> createLightWeightProxy( std::unique_ptr<IConnection>&& connection
, ServiceName destination
, ObjectPath objectPath )
{
return createProxy(std::move(connection), std::move(destination), std::move(objectPath), dont_run_event_loop_thread);
}
std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, ObjectPath objectPath )
{
@ -428,4 +435,9 @@ std::unique_ptr<sdbus::IProxy> createProxy( ServiceName destination
, dont_run_event_loop_thread );
}
std::unique_ptr<sdbus::IProxy> createLightWeightProxy(ServiceName destination, ObjectPath objectPath)
{
return createProxy(std::move(destination), std::move(objectPath), dont_run_event_loop_thread);
}
}

View File

@ -351,7 +351,7 @@ TYPED_TEST(SdbusTestObject, CanRegisterAdditionalVTableDynamicallyAtAnyTime)
, sdbus::return_slot );
// The new remote vtable is registered as long as we keep vtableSlot, so remote method calls now should pass
auto proxy = sdbus::createProxy(SERVICE_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread);
auto proxy = sdbus::createLightWeightProxy(SERVICE_NAME, OBJECT_PATH);
int result{};
proxy->callMethod("subtract").onInterface(interfaceName).withArguments(10, 2).storeResultsTo(result);
@ -370,6 +370,6 @@ TYPED_TEST(SdbusTestObject, CanUnregisterAdditionallyRegisteredVTableAtAnyTime)
vtableSlot.reset(); // Letting the slot go means letting go the associated vtable registration
// No such remote D-Bus method under given interface exists anymore...
auto proxy = sdbus::createProxy(SERVICE_NAME, OBJECT_PATH, sdbus::dont_run_event_loop_thread);
auto proxy = sdbus::createLightWeightProxy(SERVICE_NAME, OBJECT_PATH);
ASSERT_THROW(proxy->callMethod("subtract").onInterface(interfaceName).withArguments(10, 2), sdbus::Error);
}