8000 ⚡zb,zm: Proxy await properties by KmolYuan · Pull Request #1414 · dbus2/zbus · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

⚡zb,zm: Proxy await properties #1414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

KmolYuan
Copy link
Contributor
@KmolYuan KmolYuan commented Jun 29, 2025

Fix #1412.

Add wait_property_for method for Proxy/blocking::Proxy and generate wait_*_for methods in the proxy macro.

@KmolYuan KmolYuan force-pushed the proxy-await-properties branch from 2966cdc to ee69df1 Compare June 29, 2025 03:40
///
/// Note that zbus doesn't queue the updates. If the listener is slower than the receiver, it
/// will only receive the last update.
pub async fn wait_property_for<T>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm now wondering, isn't this achieving the same as you could with futures API easily? 🤔

Copy link
Contributor Author
@KmolYuan KmolYuan Jun 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a convenience function of

use futures::{FutureExt as _, StreamExt as _};

let name;
let predicate;
let fut = {
    let event_stream = (proxy.receive_property_changed(name).await)
        .then(|ev| async move { ev.get().await });
    let mut stream = std::pin::pin!(
        futures::stream::once(proxy.get_property::<T>(name).await)
            .chain(event_stream) // impl Stream<Item = zbus::Result<T>>
            .filter(predicate)
    );
    // the future roughly equivalent to `proxy.wait_property_for(name, predicate)`
    stream.next().map(|item| item.unwrap()) // impl Future<Output = zbus::Result<T>>
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a convenience function of

Right but do you really need to create a future here? 🤔

use futures::{FutureExt as _, StreamExt as _, TryStreamExt as _};

let name;
let predicate;

let event_stream = (proxy.receive_property_changed(name).await)
    .then(|ev| ev.get())
    .try_filter(predicate);
let next_prop_value = event_stream.try_next().await?;

Something like that should work, no? Our binary size is already big (#304) so I'm just wondering if this is a frequently used enough API to justify its existence in zbus, if futures already provide an API to easily do what you need.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the shortcoming of the property changed stream is that it doesn't return the current value to check if the current value already meets the requirement. Otherwise, the receive_property_changed method is enough.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the shortcoming of the property changed stream is that it doesn't return the current value to check if the current value already meets the requirement.

Huh? That's what the try_filter in my example do.

Copy link
Contributor
@zeenix zeenix Jun 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, I'm not saying that PropertyChangedStream already does the whole thing you need. My point was that combined with futures (which is already our dep) API, what you need can likely be achieved with a few LOC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, I'm not saying that PropertyChangedStream already does the whole thing you need. My point was that combined with futures (which is already our dep) API, what you need can likely be achieved with a few LOC.

Sure, adding a filter or checking values in loops is the solution we are currently using. But based on the reliance on compile-time checking (property names), we made separate methods for different properties due to they are difficult to generalize.

If there are some settings on the PropertyStream type, it can also solve the problem.

let mut stream = proxy.receive_foo_changed().await.with_current();

Copy link
Contributor
@zeenix zeenix Jun 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, adding a filter or checking values in loops is the solution we are currently using.

That's not the solution I suggested but that works too. The main point is that as long as it's easy and needs a few LOCs, probably not a good idea to add more API to zbus unless we've reasons to believe that it's going to be useful for a big percentage of our users.

. But based on the reliance on compile-time checking (property names), we made separate methods for different properties due to they are difficult to generalize.

You can create a generic API that deals with PropertyStream so you can use it with the result so any receive_*_changed method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proxy API to await specific changes in properties
2 participants
0