mavlink / MAVSDK-Java

MAVSDK client for Java.
71 stars 41 forks source link

blockingFirst race condition #3

Closed RyanHurst closed 5 years ago

RyanHurst commented 5 years ago
Telemetry telemetry = new Telemetry();
telemetry.armed().subscribe(armed -> logger.debug("armed: " + armed));
logger.debug("blocking armed: " + telemetry.armed().blockingFirst());

so I’ve found a strange race condition. sometimes this will output:

16:52:26.985 [main] DEBUG io.dronecode_sdk.telemetry.Telemetry - Building channel to 127.0.0.1:50051
16:52:28.145 [grpc-default-executor-2] DEBUG io.dronecore.example.DroneCoreExample - armed: false
16:52:29.140 [grpc-default-executor-2] DEBUG io.dronecore.example.DroneCoreExample - armed: false
16:52:30.140 [grpc-default-executor-2] DEBUG io.dronecore.example.DroneCoreExample - armed: false
16:52:31.140 [grpc-default-executor-2] DEBUG io.dronecore.example.DroneCoreExample - armed: false

and then it will just repeat indefinitely

then sometimes this will output:

16:54:49.835 [main] DEBUG io.dronecode_sdk.telemetry.Telemetry - Building channel to 127.0.0.1:50051
16:54:51.246 [main] DEBUG io.dronecore.example.DroneCoreExample - blocking armed: false

Process finished with exit code 0
JonasVautherin commented 5 years ago

What happens here is that in the C++ SDK, we currently only register one callback. With your code above, it does register armed() twice, and therefore only one stays. We don't want that behavior in Java.

So the solution is, in the Java SDK, to share() the stream (Flowable) between all the callers, so you can call telemetry.armed().subscribe() as many times as you want. That's how we do in the Swift SDK already.