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

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

          People

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

            Dates

            • Created:
              Updated:
              Resolved: