Uploaded image for project: 'Wicket'
  1. Wicket
  2. WICKET-5243

JS: High stack size in Function Executor causes "too much recursion"

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 6.8.0
    • Fix Version/s: 7.0.0-M1, 6.15.0
    • Component/s: wicket
    • Environment:
      Tested on Firefox

      Description

      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).

      The problem is that the majority of tasks don't need to wait but return instantly instead. Examples: exchanging components, executing custom javascripts that do not use the "|-syntax" to include the notify callback.

      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.
      • if an executed custom javascript creates a big stack itself (e.g. by using jquery a lot) the stack will add to the stack used by the Function Executor so that it may still be too big.

      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.

        Attachments

        1. WICKET-5243-avoid-recursion.patch
          5 kB
          Tobias Haupt
        2. response.xml
          486 kB
          Tobias Haupt
        3. WICKET-5243-notify-only-when-async.patch
          5 kB
          Martin Grigorov
        4. wicket-ajax-jquery.js
          81 kB
          Martin Grigorov

          Issue Links

            Activity

              People

              • Assignee:
                mgrigorov Martin Grigorov
                Reporter:
                tobiashaupt Tobias Haupt
              • Votes:
                1 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: