The Function Executor in wicket-ajax-jquery.js uses recursion and deferred calls to the notify() function to ensure synchronous execution of all tasks contained in an AjaxResponse.
Each task calls notif() when it is finished. This causes a recursive call to processNext() thus raising the stack for each execution. If there are a lot of task to handle, the stack size will increase beyond the possible stack size in the client causing a "too much recursion" exception and increasingly low performance.
The deferred execution of notify is only necessary if the task executor has to wait for long running tasks to finish at some uncertain point in the future. Examples: downloading of external resources (js, css, images). These task can call back the executor as soon as they are really finished (e.g. load event triggerd).
Current fix: The depth of the stack is counted and if a depth of >= 1000 is reached, a timeout will interrupt the synchronous task queue execution. A new executor will continue with an empty stack.
Problems with that approach:
- why 1000?
- several ajax requests might interrupt each other because the synchronous execution is broken.
Proposal to fix this: see also the attached patch.
Another callback notifyContinue() is supported that can be called whenever the task will return instantly. This callback avoids the recursive call to processNext and continues in a simple loop over all the tasks.