Vaadin doesn't store any information about messages that are sent from server to client (and vice versa) and triggers a full page reload in browser, when the server detect a mismatch between UI state on client and server, e.g. when message is lost.
This may happen due to various reasons, but those caused by network issues / message loose, can be reliably eliminated by implementing two-side message buffer for already sent, but not-yet-confirmed messages. Server can store an ordered log/buffer of UIDL messages and client can store a similar log/buffer for RPC message. The messages are preserved in buffer until a consumer (may be a server or client, depending who sends the message) confirms that it has received the message in the next request, then the producer deletes this message from the buffer.
Describe the solution you'd like
Flow Client (MessageSender) and Flow Server (ServerRPCHandler) have the logs (buffers) of ordered messages that producer (either Flow server for UIDL or Flow client for RPC) has sent to consumer.
These logs has message JSONs mapped to the sync ID or client ID. These IDs are already being used for detecting a out of sync.
Producer stores a message in the log until it gets a confirmation from the consumer.
Once a consumer sends another request (e.g. client sends another RPC for another user action), then the producer checks if this request has a confirmation for previously sent message (e.g. for the previous UIDL update that server sent to client). If the confirmation is there, then server deletes the corresponding message from the buffer, otherwise it re-sends it again in the current response along with the current UI update. Then the consumer receives two responses instead of one (if, of course, message is not lost again).
This is illustrated by the sequence diagram below: first UIDL message is logged, then deleted after confirmation. Second UIDL message is lost and server re-sends it again after action 3. Then browser receives two UIDL messages (2 and 3), updates the UI and sends the confirmation in the next request.
Acceptance Criteria:
[ ] Vaadin implements "Fault-tolerance messaging" against message loose due to various network errors by using message buffers on both sides. Server (Flow server) maintains a message buffer for UIDL messages that it sends upon request from browser. Browser (Flow client) maintains a similar message buffer for RPC messages that it sends upon end-user actions. UIDL message log is per UI instance.
[ ] The messages in buffers are discarded once a confirmation is received from the consumer, in the same time the producer keeps the message(s) in the buffer and sends them in a response until it gets a confirmation.
[ ] Buffers have a guard agains message overflow, e.g. due to unexpected producing of the messages, bugs in Vaadin.
[ ] Consumer doesn't send a confirmation immediately, but on the next request to producer, to avoid extra traffic.
[ ] Producer is able to send multiple messages in a single response, e.g. two or more UIDL JSONs, and consumer is able to process them in order.
[ ] This buffering mechanism is applied to all existing logic, where server decides to trigger a re-sync (full page reload), except cases, when Vaadin cannot avoid this re-sync, e.g. when an intermediate state is lost and producer cannot re-send it, i.e. oldest server side message has bigger ID than current ID on client, that may happen because of misconfiguration of sessions replication. In such a cases Vaadin logs an error message giving a root cause explanation and a way to eliminate it, then makes a re-sync.
[ ] Stateless applications are not affected by this feature and works as previously.
Additional context
Better to do it in two steps:
apply only the server-side buffer, release/test/monitor/fix issues.
apply the client-side buffer.
Target Vaadin release - 24.6, but can be picked to older versions.
Describe your motivation
Vaadin doesn't store any information about messages that are sent from server to client (and vice versa) and triggers a full page reload in browser, when the server detect a mismatch between UI state on client and server, e.g. when message is lost.
This may happen due to various reasons, but those caused by network issues / message loose, can be reliably eliminated by implementing two-side message buffer for already sent, but not-yet-confirmed messages. Server can store an ordered log/buffer of UIDL messages and client can store a similar log/buffer for RPC message. The messages are preserved in buffer until a consumer (may be a server or client, depending who sends the message) confirms that it has received the message in the next request, then the producer deletes this message from the buffer.
Describe the solution you'd like
Flow Client (
MessageSender
) and Flow Server (ServerRPCHandler
) have the logs (buffers) of ordered messages that producer (either Flow server for UIDL or Flow client for RPC) has sent to consumer.These logs has message JSONs mapped to the sync ID or client ID. These IDs are already being used for detecting a out of sync.
Producer stores a message in the log until it gets a confirmation from the consumer. Once a consumer sends another request (e.g. client sends another RPC for another user action), then the producer checks if this request has a confirmation for previously sent message (e.g. for the previous UIDL update that server sent to client). If the confirmation is there, then server deletes the corresponding message from the buffer, otherwise it re-sends it again in the current response along with the current UI update. Then the consumer receives two responses instead of one (if, of course, message is not lost again).
This is illustrated by the sequence diagram below: first UIDL message is logged, then deleted after confirmation. Second UIDL message is lost and server re-sends it again after action 3. Then browser receives two UIDL messages (2 and 3), updates the UI and sends the confirmation in the next request.
Acceptance Criteria:
Additional context
Better to do it in two steps:
Target Vaadin release - 24.6, but can be picked to older versions.