-
Notifications
You must be signed in to change notification settings - Fork 66
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
Firestore.runTransaction should support/recognize asynchronous updateFunction result #43
Comments
Your first resolution doesn't seem doable. If I think that this needs more design work before this is actionable. |
You are right. The suggested code does not work. Moreover it's not a clean approach anyway. The other suggestions are however still valid, I think. |
What exactly do you mean by this? This is async from the perspective of calling thread as well as the internal thread. This is getting wrapped in to async function internally see here. does your update function depend on some other async function? If thats the case then probably you should run this whole transaction after your async function is done. would that work? |
I am discussing: callbackResult.set(transactionCallback.updateCallback(transaction)); You are describing what happens after the updateCallback() is invoked: we have the result of type T and an asynchronous result processing happens. However, what I mean is how you get the return value of udpateCallback(tx) - you retrieve this synchronously and it must be of type T, not ApiFuture, unfortunately:
Let's pretend that in the updateCallback(tx), I am doing some RESTful I/O. I would like to provide the result asynchronously - because I am using netty for example. But, instead I have to block the thread executing updateCallback(tx), because I need to provide the result of type T synchronously. This is the wasting of precious resources I am talking about. Is that now clearer? |
@pavelkryl Can you do Rest operation first and then call runTransaction? runTransaction is the actual public interface, which is async. |
@ajaaym Yes I can. But this debate is a conceptual one. Doing a RESTful call is just one example of hundreds of usecases where asynchronous interaction would suit better than a synchronous one. Similarly I could ask: could you pre-compute the value Moreover in the transaction callback you will often call firestore API to read a document - Please distinguish between Suggested SolutionPresuming that you support async callback:
The implementation is that simple:
This does not seem to me that complicated, but the benefit it brings is huge. |
Hey, could someone answer me - or oppose the idea? |
Hey, why isn't anybody replying to my ingenious suggestion? :) This is 30 line improvement with huge implications - supporting fully asynchronous execution. |
Thanks for creating and managing Firestore. I have one suggestion for improvement though.
Currently I consider Firestore admin API to be just partially asynchronous. Whenever there is a call which returns ApiFuture, I consider it OK, although far from ideal comparing to RxJava/reactor Single/Observable/Mono/Flux. I can do conversion from ApiFuture to Mono quite easily by myself.
Problem
The Firestore.runTransaction() has a problem: result of the runTransaction is OK (it's ApiFuture). The transaction update function, however, must provide a result synchronously:
When I track down to the point where the function is executed, I observe:
This implies, that that whole body of the update function is executed in a blocking way, thus wasting precious resources.
Resolution
My suggestion for improvement is instead of calling callbackResult.set(transactionCallback.updateCallback(transaction)), it would be better to distinguish asynchronous result and do the invocation specifically:
With this implementation, I could implement body of the update function in a fully reactive way and convert the result to ApiFuture (SettableApiFuture).
Alternatives
A cleaner solution - describing the contract more clearly - would be to have separate interface for asynchronous update function:
And then specific method for executing AsyncFunction instead of Function. Actually anything which somehow allows me to do asynchronous transaction execution would offer me the required flexibility/efficiency.
Another alternative would be to provide fully reactive API (returning Mono/Single), but I understand that you do not want dependency on particular vendor (RxJava, Spring reactor). Maybe, however, you could consider switching to reactive streams Publisher, which is becoming the common shared API/standard for reactive programming in Java.
The text was updated successfully, but these errors were encountered: