Hello.
We are still working on application which should react to ledger changes and updated ledger depending on current ledger state and application settings. We got rid of all blocking calls since previous question - DamlLedgerClient deadlock
But now when we tried to subscribe to results of CommandClient.submitAndWait methods, we found out that resulting Single instances are blocking. So, when we try to use subscribe on that Singles we have current thread blocked and callback called synchronously.
This happens because these Singles are created using Single.fromFuture method, which uses FlowableFromFuture class, which subscribeActual method has blocking implementation.
We created simple tesing code to show this behavior here - GitHub - digital-asset/ex-java-bindings: Three examples demonstrating three different approaches to using the Java ledger API bindings . You can see logs with stack traces there in PingPongReactiveMain class on lines 105 and 117.
We are unable to find workarounds for this issue cause issue is introduced by Reactive Layer of Daml Java Bindings.
What can you suggest us to do?
BTW, you can see discussion of similar issue on Stackoverflow - rx java2 - RxJava How to create a non blocking Single from CompletableFuture<Long> - Stack Overflow
Regards,
Alexey.
Thanks for the feedback, Aleksei. This is very valuable and I’ll make sure to create a ticket to track this.
If the blocking behavior is a deal breaker for you and you need a short term solution, you can use the gRPC generated code directly. It’s a bit unwieldy but it should allow you to move past this obstacle. We are starting to have discussions about how we want to evolve our Java bindings and we’ll certainly fix existing bugs, but we have pressing priorities that could make this particular item slip a bit.
I’m wondering if another possible short term solution could be to wrap the Single
coming back from the bindings into a separate implementation of Single
that does the wrapping suggested in the StackOverflow answer you shared, calling the toFuture
method of Single
on the original one. It’s a bit convoluted but could serve the purpose.
I created the workaround using Reflection. You can find it within this commit: Added TemporaryFixes.fixSingleFromListenableFuture initial implementa… · alekseilarionovepam/ex-java-bindings@99c39a1 · GitHub
Hope it is temporary solution and you will use:
Single.create(subscriber ->
Futures.addCallback(listenableFuture, new FutureCallback() {
@Override
public void onSuccess(@Nullable Object t) {
subscriber.onSuccess(t);
}
@Override
public void onFailure(Throwable throwable) {
subscriber.onError(throwable);
}
}, Runnable::run))
instead of:
Single.fromFuture(listenableFuture)
in next version of Daml SDK.
1 Like
Thanks for letting us know. I cannot guarantee that this will be fixed by the next SDK release as we have high priority work that has already been scheduled, but it’s definitely going to come in a future release.