DataTables serverSide retries: duplicate writes and stale draw handling
0 reputation · 28 Jan 2022, 04:10 UTC
0 reputation · 28 Jan 2022, 04:10 UTC
DataTables serverSide processing sends a draw counter with each request and expects the server to echo it so the client can discard stale responses. Core DataTables documents no automatic retry for failed or timed-out Ajax, and ajax.reload() may overlap an in-flight request. Writes typically live outside core DataTables in Editor or custom endpoints, so retrying a POST after an ambiguous timeout can duplicate a row unless the application defines its own idempotency semantics.
The unresolved decision is how to reconcile read sequencing with write safety. Should a failed serverSide read be retried with the same draw value or a new one, and should a stale response be ignored once a newer request has succeeded? Version-sensitive differences in ajax options, serverSide defaults, and preXhr/xhr events across DataTables 1.x and 2.x make it unclear where to enforce these rules.
Should the application mint a stable idempotency key before the first write attempt and hold it until a definitive result, or is there a supported client-side pattern to block overlapping triggers and queue retries while preserving draw ordering?
DataTables uses the `draw` parameter to sequence requests. When a request is sent, the client increments this counter; the server must echo this value in the JSON response. If a response arrives with a `draw` value lower than the one currently displayed, DataTables automatically discards it as stale.
When retrying a failed server-side read:
Because DataTables core is focused on data display, it does not provide safety for POST/PUT operations. To prevent duplicate rows during retries, you must implement a stable idempotency key strategy.
The Recommended Pattern:
To prevent `ajax.reload()` or other triggers from firing overlapping requests, use a client-side flag or a queue within the `preXhr` or `xhr` events. This ensures only one mutating request is in-flight at a time.
// Simple lock to prevent overlapping requests
var isProcessing = false;
table.ajax.reload([], {
preXhr: function(xhr) {
if (isProcessing) {
xhr.abort();
return;
}
isProcessing = true;
},
complete: function() {
isProcessing = false;
}
});
Diagnostic Question: Are your write operations handled via DataTables Editor, or through custom API endpoints where you manage the Ajax request-response lifecycle manually?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.