diwic / dbus-rs

D-Bus binding for the Rust language
Other
591 stars 133 forks source link

"Path, Interface, or Method does not exist" on startup #472

Closed debug-richard closed 4 months ago

debug-richard commented 4 months ago

I have implemented a dbus system bus service using the tokio crossroads example (https://github.com/diwic/dbus-rs/blob/master/dbus-tokio/examples/tokio_server_cr.rs) and in general it is working great!

But there is one issue, system (bus) services are usually started upon request.
When my client does the first call I always get the error message "Path, Interface, or Method does not exist".
Further calls work as expected.

I haven't looked deep into the code, but if we look at the example, this seems to be a valid error. https://github.com/diwic/dbus-rs/blob/43a2da1b0b6609dada82aa0e08c857a1de569e2f/dbus-tokio/examples/tokio_server_cr.rs#L15-L28

Note: I changed connection::new_session_sync() -> connection::new_system_sync() It looks to me like the API is registered first and then the interface/methods are added, but after registration it is already callable.

My python services which use dbus-python/PyGObject do not have this issue.

There must be a way to register the service without publishing it immediately, but dbus-rs does not seem to offer such an option at this point.

diwic commented 4 months ago

Not sure in which order things should startup in order to avoid race conditions, but how about doing things in another order, i e, move these lines:

 let _handle = tokio::spawn(async {
    let err = resource.await;
    panic!("Lost connection to D-Bus: {}", err);
});
c.request_name("com.example.dbustest", false, true, false).await?;

...after everything crossroads?

debug-richard commented 4 months ago

I have just tried this and can no longer reproduce the error! Did not see that this is decoupled... Thank you for your fast support!

I am doing now:

  let _handle = tokio::spawn(async {
      let err = resource.await;
      panic!("Lost connection to D-Bus: {}", err);
  });
  c.request_name("com.example.dbustest", false, true, false).await?;
  future::pending::<()>().await;

Maybe it is a good idea to update the examples