Tapestry 5
  1. Tapestry 5
  2. TAP5-256

Page Pool Limit exhausted when exception occurs (during PageAttached lifecycle) on a link

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.0.15
    • Fix Version/s: 5.0.16
    • Component/s: tapestry-core
    • Labels:
      None

      Description

      Whenever an exception occurs on a linked page (PageA in the attached example code), the size of the "inUse" LinkedList is never reset. The reason for this is that Tapestry has no chance to mark the page causing the exception (PageA) as dirty and add it to the request page cache. Therefore at the end of the request, when the thread cleanup event occurs, the page in error is never removed (when dirty) and released. However the requested page (PageB in the attached JMeter test) is marked as dirty and added to the request page cache and is subsequently removed and released.

      I have attached a sample project which has 3 pages (PageA, PageB, and PageC). On each page, there is side menu that links to PageA, B and C. In PageA during the PageAttached lifecycle, I have added a Runtime exception (note that in our production environment we are getting Connection reset exceptions). To run this application, you need to do the following:

      • Extract the attached tutorial1.zip
      • mvn clean install
      • mvn jetty:run

      A Jmeter test (PagePoolLoadTest.jmx) has also been provided, to automatically go to PageB and assert that the exception generated by PageA exists as part of the response. The test has 20 concurrent users which should run successfully during the first attempt. However, during the second attempt, the test should fail because Tapestry will report that page pool limit exceeded for PageA eventhough there are only 20 concurrent users.

      The patch I applied to our production version of Tapestry (5.0.15) is to modify the RequestpageCacheImpl get method to catch the RuntimeException and mark the page as dirty and add it to the request page cache:

      public Page get(String logicalPageName)
      {
      Page page = cache.get(logicalPageName);

      if (page == null)
      {
      page = pagePool.checkout(logicalPageName);

      try

      { page.attached(); cache.put(logicalPageName, page); }

      catch(RuntimeException e)

      { page.incrementDirtyCount(); cache.put(logicalPageName, page); throw e; }

      }

      return page;
      }

      1. PagePoolLoadTest.jmx
        10 kB
        Carlo Simbag
      2. tutorial1.zip
        36 kB
        Carlo Simbag

        Activity

        Carlo Simbag created issue -
        Carlo Simbag made changes -
        Field Original Value New Value
        Attachment tutorial1.zip [ 12391702 ]
        Attachment PagePoolLoadTest.jmx [ 12391703 ]
        Howard M. Lewis Ship made changes -
        Status Open [ 1 ] Closed [ 6 ]
        Fix Version/s 5.0.16 [ 12313427 ]
        Assignee Howard M. Lewis Ship [ hlship ]
        Resolution Fixed [ 1 ]

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Carlo Simbag
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development