openbmc / sdbusplus

C++ bindings for systemd dbus APIs
Apache License 2.0
104 stars 82 forks source link

Parallel method calls not getting executed in multiple server threads when using ASIO #61

Closed pramorag closed 3 years ago

pramorag commented 3 years ago

Hi All,

I am trying to model a DBUS service with various interfaces and methods using ASIO and using a "single" ASIO iO_context with "multiple" worker pthreads executing io.run() on this context.

(i) I assume that whenever a DBUS client calls an interface.method(), one of the threads running io.run() will execute the method (which is happening fine).

(ii) Now, when another DBUS client invokes the same or a different interface.method(), it doesn't get executed in parallel to the above method, though I have many worker threads running io.run().

Once the first thread finishes executing the method in (i), it picks up the new DBUS message in (ii) and executes it. So, only a single thread is executing methods in a service serially and no parallel execution is happening. This thread is one among the worker threads and gets chosen randomly by ASIO.

Why is the parallel method execution not happening? Am I missing something OR do I need to configure Boost.asio library differently?

Please advise.

Thanks and Best Regards, Pramod

williamspatrick commented 3 years ago

It does not appear that the underlying systemd dbus libraries are intended to be used by parallel threads. I glanced quickly at their code and there is zero implementation of any thread safety. I would strongly discourage you from attempting to run bus operations from multiple threads.

mdmillerii commented 3 years ago

https://systemd-devel.freedesktop.narkive.com/8EpFxllx/libsystemd-should-each-thread-open-its-own-dbus-connection-sd-bus#:~:text=sd-bus%20is%20not%20thread-safe%20on%20is%20own

definitive statement agrees

pramorag commented 3 years ago

Hi Patrick (@williamspatrick) , Milton (@mdmillerii),

I was using the example from "sdbusplus/example/asio-example.cpp" and wanted to understand whether the purpose of using Boost::Asio is only for "clients" to invoke methods asynchronously?

Can we also have a similar thing on "server" side where multiple client method requests can be handled by the server process "concurrently" using Boost::Asio?

Thanks, Pramod

edtanous commented 3 years ago

boost asio implements a proactor pattern. Technically nothing operates explicitly in parallel, but if coded correctly, when operations would block, they are added back to the main reactor so that blocking doesn't happen and other tasks can continue while the operation is waiting. This is all done via a single thread in most openbmc applications, which makes sense, as most BMCs are single processor, so even if we could multi-thread, we'd never get more performance from parallelism.

To answer the original bug, if you must implement multi-threading, you will either need to implement it in the application code around sdbusplus, or implement a "connection per thread" model in your code.

pramorag commented 3 years ago

Thanks, Ed (@edtanous) for your response.

So essentially, the implementation in "sdbusplus/sdbusplus/include/sdbusplus/asio" is catered towards the "client-side" code for invoking async calls and not for the server-side of things (say, for handling multiple D-BUS requests from clients simultaneously)?

Thanks, Pramod

williamspatrick commented 3 years ago

So essentially, the implementation in "sdbusplus/sdbusplus/include/sdbusplus/asio" is catered towards the "client-side" code for invoking async calls and not for the server-side of things (say, for handling multiple D-BUS requests from clients simultaneously)?

No, not necessarily. We use it for server implementations as well. It just doesn’t do parallel / multi-threaded handling of requests. But, it is used in case where the server results require some longer activity to get the client answer. For instance, dbus activity to another daemon or a long hardware access.

pramorag commented 3 years ago

Thanks for your reply, Patrick (@williamspatrick)

Can you please point me to an example server(s) that is(are) doing this?

Thanks!