I have an issue with a Usecase where a Field is changed, and the FocusLost Event triggers (outside the Vaadin Frame) a call to a JavascriptFuntion that is registered in Vaadin. This caused the rpc queue to have 2 interactions in the same request: the field change + the JS-Function call.
In our specific case, we need the JS-Function to be called after the field change has finished, because the JS Function might remove the Component where the Field is from the UI. If the component is restored, the field change is lost.
Is there a way to control the excecution order, or to force some calls to be forced in a separate request?
I’ll preface this all by saying that this is not something I’ve tried, it’s all from looking at code and that the code in question is not guaranteed to stay the same in future versions.
Looking at
JavaScriptManagerConnector.java , looks like it might be possible to write an Extension for the Field that works as described. Instead of registering a global JS function from the server side, create it in the Extension and call the client-side Java code using
JSNI .
In the Java code, manually get the
ServerRpcQueue like in JavaScriptManagerConnector and call serverRpcQueue.flush(). Looking at ServerRpcQueue, the flush method doesn’t do anything if a flush is already pending; I’m not sure if that is true when the FocusLost event has triggered. If so, you’ll need to get even more creative.
You could try to call getAll() to get all of the pending invocations, clear() to remove them from ServerRpcQueue and use add() to add them back in in the wanted order. The data structure used for pendingInvocations is a LinkedHashMap, so at least it guarantees the order.
Again, even if the above works, it’s not a very common solution. ServerRpcQueue might change later. It’s also probably quite easy to get things wrong in some subtle way and it could cause some really confusing bugs. But if you really need to get this done and you haven’t got any other options (like somehow semaphoring the state on server side), I suppose it’s worth a try.
we might give this a try. I was hoping for some easy way to do this. However, maybe we should first understnad how the rpc queue works…
In our specific case, we get a queue with for example 2 items:
field change event
jsCall from outside the browser which triggers a JSComponent of our own.
I notice that many times, when the jsCall comes in the same request as the field change (jsCall is always after fieldChange in the list), the fieldChange gets lost (cannot say if it is not executed or simply happens out of sync, there is no exception thrown). Are the rpcQueue items processed in one thread? Is the order always as received? Why could one event get lost, even though it is in the request?
The requests are stored as a single JSON message on the client side, sent to the server, parsed and iterated in a loop. All the data types used (including JsonArray) should be ordered and there’s no parallel processing involved, so I can’t see where the order would change. In addition to
ServerRpcQueue 's toJson method, see
MessageSender (client side) and
ServerRpcHandler (server side). If an event really gets lost, I’d consider that a fairly major bug; you could try debugging the above methods to see what’s going on.
we are not expecting any mayor bug. As far as I have testet, I think that all cases where the rpc events are inside a single request, Vaadin seems to be processing them in the right order (and we are getting the expected result).
I still have some cases where the field change gets lost, but I am suspecting that it always happens on widgets where a flush of the queue happens just after the field change anyhow, and our following event travels in a separate request…
As these requests can be processed in parallel at the server, the behaviour that the first event gets lost “some of the times” is easy to explain.
Now we have to see if there is a way to make sure our last event is sent only after we can confirm that everything else has been processed, but that does not have anything to do with Vaadin.
I will be monitoring the behaviour, if I see any events that are in the right order, but one gets lost in the same request, I will try to post it in detail in this thread… Otherwise the issue might not be relevant anymore…