Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.7.1
    • Component/s: None
    • Labels:
      None
    • Environment:
      ICEfaces, Ajax Push
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial

      Description

      The current RenderManager API offers a high degree of control over server-initiated rendering, but provides more power than necessary for simple applications. The SessionRenderer provides a more basic API as follows:

      public class org.icefaces.application.SessionRenderer extends java.lang.Object{
          public static synchronized void addCurrentSession(java.lang.String groupName);
          public static synchronized void removeCurrentSession(java.lang.String groupName);
          public static void render(java.lang.String groupName);
      }

      A sample invocation, such as in the auctionMonitor would be

      In a bean constructor:

      SessionRenderer.addCurrentSession("auction");

      When an event occurs:

      SessionRenderer.render("auction");

      The SessionRenderer is responsible for the maintenance of the lists of HttpSessions/PortletSessions. Lists of Views are obtained from the ICEfaces infrastructure. RenderingException is not passed to the application because, in this case, the application is only concerned with pushing updates to active users. If users are not active, they are automatically garbage collected.

        

        Issue Links

          Activity

          Hide
          Ted Goddard added a comment -

          Prototype implemented, pending checkin.

          Show
          Ted Goddard added a comment - Prototype implemented, pending checkin.
          Hide
          Deryk Sinotte added a comment -

          The goal of a simpler API for certain use cases is definitely a good thing. My comments on the suggested API (without seeing the implementation):

          The name, SessionRenderer suggests to me that it's bound to a session - an individual user. Rather than suggesting what it does, it seems to refer to how it does it. The word "session" is a bit of an overloaded concept already when you consider the difference between Http Sessions and Portlet Sessions. However the use of "group names" as parameters suggests that this can be used across different groups of sessions. Bottom line, perhaps the class and method names could be revisited.

          This appears to only handle on-demand rendering cases (not interval or delay like the existing API). This may be intended in order for the API to remain simple.

          Without looking at the implementation, I can't tell if this uses some of our existing rendering API infrastructure (Thread pool, RenderHub) or not. If it doesn't, then I'd like to see how it does do things so I could comment more fully.

          Show
          Deryk Sinotte added a comment - The goal of a simpler API for certain use cases is definitely a good thing. My comments on the suggested API (without seeing the implementation): The name, SessionRenderer suggests to me that it's bound to a session - an individual user. Rather than suggesting what it does, it seems to refer to how it does it. The word "session" is a bit of an overloaded concept already when you consider the difference between Http Sessions and Portlet Sessions. However the use of "group names" as parameters suggests that this can be used across different groups of sessions. Bottom line, perhaps the class and method names could be revisited. This appears to only handle on-demand rendering cases (not interval or delay like the existing API). This may be intended in order for the API to remain simple. Without looking at the implementation, I can't tell if this uses some of our existing rendering API infrastructure (Thread pool, RenderHub) or not. If it doesn't, then I'd like to see how it does do things so I could comment more fully.
          Hide
          Ted Goddard added a comment -

          A prototype of the API has been checked in for inspection and modification.

          The API is deliberately based on Session (Servlet or Portlet) because this concept is already familiar to the developer. If all portlets open by a particular user are in the same PortletSession, then this is appropriate.

          The implementation does not make use of RenderManager, but it should either apply the same pooling techniques, or directly make use of RenderManager functions (possibly exposed slightly differently for system use).

          It is intended that this API support clustering through a simple mechanism of specifying which groups should be broadcast cluster-wide, for instance:

          enableClusterRendering(String groupPattern)
          disableClusterRendering(String groupPattern)

          i.e.

          enableClusterRendering("auction/*");

          Clustering must be enabled on a group both for it to receive and to send rendering requests in the cluster.

          One of the goals of this API is to reduce the learning curve for new uses of Ajax Push, so it is possible that clustering features should be found instead in a section of the RenderManager API that operates on SessionGroups. This would include enabling/disabling clustering, obtaining notification when a group is created or destroyed, etc.

          Show
          Ted Goddard added a comment - A prototype of the API has been checked in for inspection and modification. The API is deliberately based on Session (Servlet or Portlet) because this concept is already familiar to the developer. If all portlets open by a particular user are in the same PortletSession, then this is appropriate. The implementation does not make use of RenderManager, but it should either apply the same pooling techniques, or directly make use of RenderManager functions (possibly exposed slightly differently for system use). It is intended that this API support clustering through a simple mechanism of specifying which groups should be broadcast cluster-wide, for instance: enableClusterRendering(String groupPattern) disableClusterRendering(String groupPattern) i.e. enableClusterRendering("auction/*"); Clustering must be enabled on a group both for it to receive and to send rendering requests in the cluster. One of the goals of this API is to reduce the learning curve for new uses of Ajax Push, so it is possible that clustering features should be found instead in a section of the RenderManager API that operates on SessionGroups. This would include enabling/disabling clustering, obtaining notification when a group is created or destroyed, etc.
          Hide
          Deryk Sinotte added a comment -

          Here are my comments after looking at the implementation:

          Some of the logic in the render method for dealing with individual views is very interesting. Seems like there's a good way of dealing with multiple views that should be used more generally for all Rendering API work.

          The current SessionRenderer API doesn't use the existing Render APIs or classes at all. This has a few implications. One is that it makes it more difficult to transition from the simpler API to the more sophisticated API as the developer gains experience and the application gains complexity.

          The implementation only has a comment around requiring a thread pool - no implementation. There's a fair amount of complexity around threads created on the server-side. You can't call the JSF lifecycle from the server-side without creating your own threads. If we don't use the existing mechanisms (or come up with a shared mechanism) then we'll potentially be creating a second thread pool to handle the requirements of this API. We currently do a bunch of stuff to try and ensure the proper thread context and to work with other technologies (e.g. Seam). Admittedly, some of it could be unnecessary baggage that's been carried along from previous releases but the current implementation doesn't have any implementation or any notes on how this would be done. In my opinion, going forward, we should potentially look at using a standard library (like Quartz) and/or using the built-in APIs of the app server when available (Worker API). However, the context of those threads still need to be valid when running with other frameworks. There's some work involved in any case.

          I have some concerns about multiple render calls. With the existing Render API, multiple calls to render are handled in an efficient manner (run one, queue the next one, and throw away any others if a render is already queued). The current render method looks like it would execute the lifecycle as many times as it was called.

          There appears to be no support for anything other than on-demand style rendering. Delay rendering is a niche but interval style rendering has proven to be fairly popular.

          I agree that clustered rendering should probably be considered a more advanced feature and not part of a simplified API.

          Show
          Deryk Sinotte added a comment - Here are my comments after looking at the implementation: Some of the logic in the render method for dealing with individual views is very interesting. Seems like there's a good way of dealing with multiple views that should be used more generally for all Rendering API work. The current SessionRenderer API doesn't use the existing Render APIs or classes at all. This has a few implications. One is that it makes it more difficult to transition from the simpler API to the more sophisticated API as the developer gains experience and the application gains complexity. The implementation only has a comment around requiring a thread pool - no implementation. There's a fair amount of complexity around threads created on the server-side. You can't call the JSF lifecycle from the server-side without creating your own threads. If we don't use the existing mechanisms (or come up with a shared mechanism) then we'll potentially be creating a second thread pool to handle the requirements of this API. We currently do a bunch of stuff to try and ensure the proper thread context and to work with other technologies (e.g. Seam). Admittedly, some of it could be unnecessary baggage that's been carried along from previous releases but the current implementation doesn't have any implementation or any notes on how this would be done. In my opinion, going forward, we should potentially look at using a standard library (like Quartz) and/or using the built-in APIs of the app server when available (Worker API). However, the context of those threads still need to be valid when running with other frameworks. There's some work involved in any case. I have some concerns about multiple render calls. With the existing Render API, multiple calls to render are handled in an efficient manner (run one, queue the next one, and throw away any others if a render is already queued). The current render method looks like it would execute the lifecycle as many times as it was called. There appears to be no support for anything other than on-demand style rendering. Delay rendering is a niche but interval style rendering has proven to be fairly popular. I agree that clustered rendering should probably be considered a more advanced feature and not part of a simplified API.
          Hide
          Jack Van Ooststroom added a comment -

          The SessionRenderer API should be able to use the broadcasting capabilities automatically.

          Show
          Jack Van Ooststroom added a comment - The SessionRenderer API should be able to use the broadcasting capabilities automatically.
          Hide
          Jack Van Ooststroom added a comment -

          SessionRenderer API:

          • public static void addCurrentSession(String groupName)
          • public static void removeCurrentSession(String groupName)
          • public static void render(String groupName)

          I left Ted's suggested SessionRenderer API as is. I only removed the synchronized off each method. The RenderManager API has been made HttpSession-aware by changing the GroupAsyncRenderer:

          • public void add(HttpSession httpSession)
          • public boolean contains(HttpSession httpSession)
          • public void remove(HttpSession httpSession)

          The SessionRenderer cleverly uses the RenderManager's capabilities to provide a simpler API. It only utilizes the OnDemandRenderer. As it uses the RenderManager it automatically gains broadcasting capabilities as well. However, without the fine-grained control capabilities.

          Both the SessionRenderer API and RenderManager API can be used together in an ICEfaces application. This should be done with care!

          Marking this one as FIXED.

          Show
          Jack Van Ooststroom added a comment - SessionRenderer API: public static void addCurrentSession(String groupName) public static void removeCurrentSession(String groupName) public static void render(String groupName) I left Ted's suggested SessionRenderer API as is. I only removed the synchronized off each method. The RenderManager API has been made HttpSession-aware by changing the GroupAsyncRenderer: public void add(HttpSession httpSession) public boolean contains(HttpSession httpSession) public void remove(HttpSession httpSession) The SessionRenderer cleverly uses the RenderManager's capabilities to provide a simpler API. It only utilizes the OnDemandRenderer. As it uses the RenderManager it automatically gains broadcasting capabilities as well. However, without the fine-grained control capabilities. Both the SessionRenderer API and RenderManager API can be used together in an ICEfaces application. This should be done with care! Marking this one as FIXED.
          Hide
          Jack Van Ooststroom added a comment -

          HttpSession should not be part of the public API as it makes the servlet-api.jar a mandatory lib at compile time for applications using the RenderManager API. Reopening this one.

          Show
          Jack Van Ooststroom added a comment - HttpSession should not be part of the public API as it makes the servlet-api.jar a mandatory lib at compile time for applications using the RenderManager API. Reopening this one.
          Hide
          Jack Van Ooststroom added a comment -

          I checked in the following change:

          • GroupAsyncRenderer
          • Removed the add(HttpSession), contains(HttpSession) and remove(HttpSession) methods.
          • Added the addCurrentSession(), containsCurrentSession() and removeCurrentSession() methods.
          • Internally it stores the HttpSession and PortletSession instances via a WeakReference in its Set.
          • SessionRenderer
          • Changed the addCurrentSession(String), containsCurrentSession(String) and removeCurrentSession(String) methods to use the GroupAsyncRenderer's "equivalent" methods.
          • SessionDispatcher
          • Overloaded the getSingletonSessionServlet(HttpSession) method with the getSingletonSessionServlet(String sessionId) method.

          This way HttpSession and PortletSession are not publically exposed in the API, nor is the JSF API exposed.

          I successfully tested in both a servlet and portlet environment, and in both a non-clustered and clustered environment.

          Marking this one as FIXED (which Ken already did

          Show
          Jack Van Ooststroom added a comment - I checked in the following change: GroupAsyncRenderer Removed the add(HttpSession), contains(HttpSession) and remove(HttpSession) methods. Added the addCurrentSession(), containsCurrentSession() and removeCurrentSession() methods. Internally it stores the HttpSession and PortletSession instances via a WeakReference in its Set. SessionRenderer Changed the addCurrentSession(String), containsCurrentSession(String) and removeCurrentSession(String) methods to use the GroupAsyncRenderer's "equivalent" methods. SessionDispatcher Overloaded the getSingletonSessionServlet(HttpSession) method with the getSingletonSessionServlet(String sessionId) method. This way HttpSession and PortletSession are not publically exposed in the API, nor is the JSF API exposed. I successfully tested in both a servlet and portlet environment, and in both a non-clustered and clustered environment. Marking this one as FIXED (which Ken already did
          Hide
          Ken Fyten added a comment -

          Need to ensure this API is included in the ICEfaces JavaDoc, including the new org.icefaces.x package tree.

          Show
          Ken Fyten added a comment - Need to ensure this API is included in the ICEfaces JavaDoc, including the new org.icefaces.x package tree.
          Hide
          Jack Van Ooststroom added a comment -

          Package-level JavaDoc Description has been added. Marking this one as FIXED again.

          Show
          Jack Van Ooststroom added a comment - Package-level JavaDoc Description has been added. Marking this one as FIXED again.
          Hide
          Ted Goddard added a comment -

          updated auctionMonitor to use SessionRenderer for bid updates and chat messages. Ticking clocks still uses IntervalRenderer.

          Note that auctionMonitor had an obsolete capability for propagating events between a stock JSF implementation and an ICEfaces implementation. This event feature has been deactivated to simplify the implementation.

          Show
          Ted Goddard added a comment - updated auctionMonitor to use SessionRenderer for bid updates and chat messages. Ticking clocks still uses IntervalRenderer. Note that auctionMonitor had an obsolete capability for propagating events between a stock JSF implementation and an ICEfaces implementation. This event feature has been deactivated to simplify the implementation.

            People

            • Assignee:
              Unassigned
              Reporter:
              Ted Goddard
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: