Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-64181

Failed to pre-fetch template needs real fix

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.6
    • Fix Version/s: 3.4.7, 3.5.4
    • Component/s: JavaScript
    • Labels:
    • Testing Instructions:
      Hide
      Test 1 - concurrent async calls to render a template that loads another template.
      1. Login as an admin and go to site home.
      2. Use boost theme
      3. Copy attached modal.mustache file over theme/boost/templates/core/modal.mustache
      4. turn editing on.
      5. Reload the page 10 times
      6. Verify you do not see 'Failed to pre-fetch the template'
      7. Go to a course home page
      8. Delete an activity. 
      9. Verify you see a modal dialog to confirm that you want to delete the activity.
      Test 2. Recursive template inclusion.
      1. Log in as admin
      2. Go to the Data registry page
      3. Create a category and a purpose.
      4. Set these as the site category and purpose.
      5. Expand the Courses node inside a course category.
      6. Confirm that the courses are displayed.

      Note: Reset your Moodle code base after the test.

      git reset --hard origin/[BRANCH]
      

      substitute master, MOODLE_35_STABLE, or MOODLE_34_STABLE for [BRANCH] according to the Moodle version you're testing.

      Show
      Test 1 - concurrent async calls to render a template that loads another template. Login as an admin and go to site home. Use boost theme Copy attached modal.mustache file over theme/boost/templates/core/modal.mustache turn editing on. Reload the page 10 times Verify you do not see 'Failed to pre-fetch the template' Go to a course home page Delete an activity.  Verify you see a modal dialog to confirm that you want to delete the activity. Test 2. Recursive template inclusion. Log in as admin Go to the Data registry page Create a category and a purpose. Set these as the site category and purpose. Expand the Courses node inside a course category. Confirm that the courses are displayed. Note : Reset your Moodle code base after the test. git reset --hard origin/[BRANCH] substitute master , MOODLE_35_STABLE , or MOODLE_34_STABLE for [BRANCH] according to the Moodle version you're testing.
    • Affected Branches:
      MOODLE_36_STABLE
    • Fixed Branches:
      MOODLE_34_STABLE, MOODLE_35_STABLE
    • Pull from Repository:
    • Pull 3.5 Branch:
    • Pull Master Branch:
      MDL-64181-master

      Description

      Failed to pre-fetch template error still occurs when rendering a tree of templates from javascript twice at the same time.

      MDL-64164 is not a fix, it's just a work-around for one use-case (core/modal).

       

      History of these issues.

      When mustache was added, it was supported for php and javascript. The javascript version uses http://github.com/janl/mustache.js. When the renderer encounters a tag that requires another template, it calls a function which has to return the HTML for the template. It does not handle getting a promise - the function must return the HTML immediately. To do this we added a "pre-render" step which parses the HTML, finds all tags that include another template, generates a promise for each one to load the template via AJAX, waits for all the promises to resolve and then renders the template (and once the template is loaded it recursively does the same thing).

      The first version did not handle recursive templates rendered in javascript, it would hang for ever waiting for it's chain of promises to return.

      Process 1: wait for A raw -> wait for B raw -> wait for C raw -> wait for A raw (loop continues forever).

      We added a fix for this, but the fix is not perfect and when the same template is rendered twice in javascript at the same time and the template includes another template, the first call to render will wait correctly, but the second one will not wait for all the included templates to be ready.

      Process 1: wait for A raw -> wait for B raw -> render A
      Process 2: wait for A raw -> render A (did not wait for B!)

      To fix this we record a unique ID in each outer call to render() so we do not wait for ourselves, but we do wait if the template we need is being loaded by another different call to render().

      Not recursive:
      Process 1: wait for A raw -> wait for B raw -> render A
      Process 2: wait for A raw -> wait for B raw -> render A

      Recursive:
      Process 1: wait for A raw -> wait for B raw -> (do not wait for A because we are already waiting for it) -> render A
      Process 2: wait for A and all its dependencies-> render A

       

       

       

       

        Attachments

        1. MDL-64181.PNG
          MDL-64181.PNG
          32 kB
        2. modal.mustache
          4.77 MB

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Fix Release Date:
                  14/Jan/19

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 2 hours, 30 minutes
                  2h 30m