Skip to content

[Bug] z_scout is blocking but API and code examples suggest it is not. #1130

@Hans-Giebenrath

Description

@Hans-Giebenrath

Describe the bug

z_scout is blocking, as it uses ZRuntime::Application.block_in_place in its implementation. However, the z_scout signature, as well as code examples in this repo and in zenoh-cpp both suggest that it would be async (as are the Rust and Kotlin versions), hence this seems like a bug and not intentional.

The API uses callbacks which, at least to me, suggest that the IO work is done in the background and the callbacks will be called at some later time.
Code examples look like this:

// zenoh-c examples/z_scout.c
printf("Scouting...\n");
z_scout(z_move(config), z_move(closure), NULL);
z_sleep_s(1); // <- suggests we wait for some background task to finish.
return 0;
// zenoh-cpp examples/z_scout.cpp I made it a bit smaller
std::mutex m;
std::condition_variable done_signal;
bool done = false;

auto on_hello = [&count](const Hello &hello) { ... };
auto on_end_scouting = [&m, &done, &done_signal, &count]() { ... };

std::cout << "Scout starting" << std::endl;
scout(std::move(config), on_hello, on_end_scouting);

std::unique_lock lock(m);
done_signal.wait(lock, [&done] { return done; });

Do you agree that this leaves the impression of waiting on some background task to finish? Otherwise the sleep/mutex/... dance could be omitted.

Additionally, I noticed the following behavior (which I thought to be worth mentioning, but can't judge whether this is correct or not, so just as a side note): I created sessions and kicked off queries to the discovered routers inside of the on_hello callback, using the callback variant and they get nicely parked in the background. However, when scouting function finishes/returns (after its timeout_ms elapsed), then any pending background queries are terminated. I would have expected that they would continue to live. So right now, what I do in C++, is park the scouting function in a background thread, and use a rw-mutex to block the scout's drop handler long enough that all pending queries finished. It works, but I have the feeling that this is not the Zenoh way :)

To reproduce

In the examples/z_scout.c file, just add additional prints:

printf("Scouting...\n");
z_scout(z_move(config), z_move(closure), NULL);
printf("after scout\n");
z_sleep_s(1);
printf("after sleep\n");
return 0;

Now when you execute the example, you see this output (with the time annotations being added by me in this comment)

Scouting...
( .. 1 second of nothingness .. )
Dropping scout
Did not find any zenoh process.
after scout
( .. 1 second of nothingness .. )
after sleep

That's all, thank you!

System info

Ubuntu 24.04, zenoh-c tags/1.5.0 (I couldn't get tags/1.6.2 examples to compile atm but since the block_in_place is still there I assume it is still present there)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions