ICEfaces
  1. ICEfaces
  2. ICE-2850

Request-scoped beans getting "re-instantiated" on session expiry.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7Beta1
    • Fix Version/s: 1.7RC1, 1.7
    • Component/s: Framework
    • Labels:
      None
    • Environment:
      ICEfaces and AuctionMonitor

      Description

      It looks like on session expiry it might happen that request-scoped bean(s) get "re-instantiated" again. That is, the original request-scoped beans get cleaned up first on session expiry, but it might happen that a pending render still gets executed after that causes another instantiation of the bean being created, that doesn't get cleaned up during the lifetime of the ICEfaces application.

        Activity

        Repository Revision Date User Message
        ICEsoft Public SVN Repository #16004 Wed Mar 12 11:13:54 MDT 2008 jack.van.ooststroom Fixed JIRA ICE-2850 : Request-scoped beans getting re-instantiated on session expiry.
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/xmlhttp/PersistentFacesState.java
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/context/View.java
        Jack Van Ooststroom created issue -
        Jack Van Ooststroom made changes -
        Field Original Value New Value
        Assignee Jack van Ooststroom [ jack.van.ooststroom ]
        Jack Van Ooststroom made changes -
        Status Open [ 1 ] In Progress [ 3 ]
        Hide
        Jack Van Ooststroom added a comment -

        Changed Fix Version(s) to 1.7

        Show
        Jack Van Ooststroom added a comment - Changed Fix Version(s) to 1.7
        Jack Van Ooststroom made changes -
        Fix Version/s 1.7 [ 10080 ]
        Hide
        Jack Van Ooststroom added a comment -

        I'll try to explain in a bit more detail what I've seen happening with Auction Monitor. It seems to be reproducible quite easy with more windows open from the same browser instance all pointing to Auction Monitor.

        Auction Monitor has a request-scoped ClockBean that uses an IntervalRenderer to initiate a render every second. These render requests are put onto a queue before actually being serviced. The ICEfaces framework takes care of the actual session timeout itself. Between approximately 5 to 15 seconds before the actual session timeout would occur, the ICEfaces framework initiates its shutdown sequence for that particular session. Typically the shutdown sequence invokes the dispose() method of all related DisposableBeans. In the case of the ClockBean the dispose() method takes care of the clean up. Right after the shutdown sequence the ICEfaces framework waits for 3 seconds (to give time to other parts to finish their work as the shutdown sequence occurred) after which it invalidates the session.

        In the case of Auction Monitor, the following sequence of events could occur starting just before the session expiry:

        • the ClockBean instance requests a render
        • the shutdown sequence is initiated
        • the ClockBean instance does the clean up, making the ClockBean instance eligible for garbage collection
        • the render is serviced and because there is no ClockBean instance for this session a new instance is created
        • the new ClockBean instance is able to do one or two more successful render requests that are successfully being serviced as the actual session is still valid
        • the session is invalidated (3 seconds after the shutdown sequence was finished)
        • the new ClockBean instance will not get disposed during the duration of the application and it will continue trying to do its work (which causes Exceptions to be thrown in this particular case).
        Show
        Jack Van Ooststroom added a comment - I'll try to explain in a bit more detail what I've seen happening with Auction Monitor. It seems to be reproducible quite easy with more windows open from the same browser instance all pointing to Auction Monitor. Auction Monitor has a request-scoped ClockBean that uses an IntervalRenderer to initiate a render every second. These render requests are put onto a queue before actually being serviced. The ICEfaces framework takes care of the actual session timeout itself. Between approximately 5 to 15 seconds before the actual session timeout would occur, the ICEfaces framework initiates its shutdown sequence for that particular session. Typically the shutdown sequence invokes the dispose() method of all related DisposableBeans. In the case of the ClockBean the dispose() method takes care of the clean up. Right after the shutdown sequence the ICEfaces framework waits for 3 seconds (to give time to other parts to finish their work as the shutdown sequence occurred) after which it invalidates the session. In the case of Auction Monitor, the following sequence of events could occur starting just before the session expiry: the ClockBean instance requests a render the shutdown sequence is initiated the ClockBean instance does the clean up, making the ClockBean instance eligible for garbage collection the render is serviced and because there is no ClockBean instance for this session a new instance is created the new ClockBean instance is able to do one or two more successful render requests that are successfully being serviced as the actual session is still valid the session is invalidated (3 seconds after the shutdown sequence was finished) the new ClockBean instance will not get disposed during the duration of the application and it will continue trying to do its work (which causes Exceptions to be thrown in this particular case).
        Hide
        Jack Van Ooststroom added a comment -

        I applied two fixes:

        1. To avoid requested renders getting into the execute and render lifecycle after a shutdown occurred, I added a dispose() method to PersistentFacesState that is invoked when its associated view is disposed. When the dispose() method is invoked it simply sets a flag. Additionally, the execute() and render() methods first do a check to see if the flag is set. If it's set a FatalRenderingException is thrown to initiate additional clean up.

        2. Testing showed that SessionExpiredExceptions and IllegalStateException sometimes get wrapped into other exceptions like a FacesException for instance, causing it to be wrapped again into a TransientRenderingException in the catch-blocks of the execute() and render() methods. There is now one catch-block for Exception in which it first looks to see if the Exception itself or one of its causes is an IllegalStateException or a SessionExpiredException. If this is the case the caught Exception is wrapped into a FatalRenderingException and thrown to initiate additional clean up. Otherwise the caught Exception is wrapped into a TransientRenderingException and thrown.

        Show
        Jack Van Ooststroom added a comment - I applied two fixes: 1. To avoid requested renders getting into the execute and render lifecycle after a shutdown occurred, I added a dispose() method to PersistentFacesState that is invoked when its associated view is disposed. When the dispose() method is invoked it simply sets a flag. Additionally, the execute() and render() methods first do a check to see if the flag is set. If it's set a FatalRenderingException is thrown to initiate additional clean up. 2. Testing showed that SessionExpiredExceptions and IllegalStateException sometimes get wrapped into other exceptions like a FacesException for instance, causing it to be wrapped again into a TransientRenderingException in the catch-blocks of the execute() and render() methods. There is now one catch-block for Exception in which it first looks to see if the Exception itself or one of its causes is an IllegalStateException or a SessionExpiredException. If this is the case the caught Exception is wrapped into a FatalRenderingException and thrown to initiate additional clean up. Otherwise the caught Exception is wrapped into a TransientRenderingException and thrown.
        Michael Thiem made changes -
        Repository Revision Date User Message
        ICEsoft Public SVN Repository #16052 Mon Mar 17 17:58:08 MDT 2008 mircea.toma Change coallesing policy to allow for clean logout sequences.
        ICE-2850
        Files Changed
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/command/SessionExpired.java
        Commit graph MODIFY /icefaces/trunk/icefaces/core/src/com/icesoft/faces/webapp/command/Redirect.java
        Hide
        Jack Van Ooststroom added a comment -

        Assigning to Mircea to address the logout-login sequence issue.

        Show
        Jack Van Ooststroom added a comment - Assigning to Mircea to address the logout-login sequence issue.
        Jack Van Ooststroom made changes -
        Assignee Jack van Ooststroom [ jack.van.ooststroom ] Mircea Toma [ mircea.toma ]
        Hide
        Mircea Toma added a comment -

        Change coallesing policy to allow for clean logout sequences.
        Use DisposableBean instead of HttpSessionListener.
        Invalidate session within the 'logout' ActionListener.

        Show
        Mircea Toma added a comment - Change coallesing policy to allow for clean logout sequences. Use DisposableBean instead of HttpSessionListener. Invalidate session within the 'logout' ActionListener.
        Mircea Toma made changes -
        Status In Progress [ 3 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Ken Fyten made changes -
        Fix Version/s 1.7RC1 [ 10123 ]
        Fix Version/s 1.7 [ 10080 ]
        Ken Fyten made changes -
        Fix Version/s 1.7 [ 10080 ]
        Ken Fyten made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Assignee Mircea Toma [ mircea.toma ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Jack Van Ooststroom
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: