12 Replies Latest reply on Nov 4, 2009 11:32 AM by jbalunas

    Ajax Client-side library: ways of implementation

    pyaschenko

      Now we have to choose three way to implement RF 4.0 ajax library:

      1. Extend JSF 2.0 ajax functionality with our features.

      impossible to implement:
      - queue extentions
      - dynamic loading external scripts/css by ajax request
      - cleanup for DOM elements and components (we don't know elements that were removed from DOM)
      - logging (will be very simplified)
      - browser history support
      Limited functionality.
      Here we might be lose some compatibility with client side ajax api in future JSF releases

      2. Extend JSF 2.0 ajax functionality with our features and make changes to JSF ajax implementation for our features to provide better compatibility with our component functionality and resolve some of issues from case 1
      Here we may be resolve most of our limitations from case 1.
      Better compatibility with 3rd party components and future JSF releases because of functionality will be standardized.

      3. Replace jsf ajax by our own implementation by loading our client-side library after jsf.js
      It's huge work to implement all functionality of JSF ajax to save compatibility for JSF components and 3rd party components
      Here we might be partially lost compatibility with 3rd party components

      After a local discussions we prefer to use second variant.

      Any suggestions are welcome!

        • 1. Re: Ajax Client-side library: ways of implementation
          jbalunas

           

          "pyaschenko" wrote:

          1. Extend JSF 2.0 ajax functionality with our features.

          impossible to implement:
          - queue extentions
          - dynamic loading external scripts/css by ajax request
          - cleanup for DOM elements and components (we don't know elements that were removed from DOM)
          - logging (will be very simplified)
          - browser history support
          Limited functionality.
          Here we might be lose some compatibility with client side ajax api in future JSF releases

          Define "Extend" in more detail please?

          2. Extend JSF 2.0 ajax functionality with our features and make changes to JSF ajax implementation for our features to provide better compatibility with our component functionality and resolve some of issues from case 1
          Here we may be resolve most of our limitations from case 1.
          Better compatibility with 3rd party components and future JSF releases because of functionality will be standardized.


          How is #1's "Extend" different than #2's "Extend"? What would be done differently?

          Compatibility with 3rd party component libraries is critical. So I'm happy to see this, but wondering how?

          Also what items from #1 would be resolved, and what won't, and what is unknown?

          3. Replace jsf ajax by our own implementation by loading our client-side library after jsf.js
          It's huge work to implement all functionality of JSF ajax to save compatibility for JSF components and 3rd party components
          Here we might be partially lost compatibility with 3rd party components


          This is not an acceptable option - we can't just replace the jsf ajax code. As we know this will break compatibility.

          As we have discussed we also need to detail what is missing in jsf.js, and identify extension points and suggestions that we can forward on to the JSF EG. The Mojarra team is also willing to discuss prototyping some of these for us. If this forum post is the first part of that effort - great!!

          • 2. Re: Ajax Client-side library: ways of implementation
            pyaschenko

            We have to write our library over the JSF in 1st and 2nd cases. In the first case it will be like a JSF ajax wrapper. No changes in JSF ajax library. But in second case it will be more integrated with our components because of changes in JSF library. We just provide some of our chenges to JSF team for applying it.

            1) we just writing wrapper and trying to workaround all the extension points missed issues. In that case additional coding will be done for that workarounds.

            2) we wrinting the same wrapper for JSF mechanism as for first case, but additionally redefining or change some of original script methods in order to get needed extension points. And propose that code to JSF team. After they will apply the changes we could remove it and just use wrapper with extension points we will get.

            • 3. Re: Ajax Client-side library: ways of implementation
              nbelaevski

               

              "pyaschenko" wrote:
              we wrinting the same wrapper for JSF mechanism as for first case...

              I guess wrapper will be much more simpler if we get all necessary extension points already included in Mojarra code. Note that this approach will not work with JSF 2.0.0, only with the later versions.

              • 4. Re: Ajax Client-side library: ways of implementation
                jbalunas

                 

                "pyaschenko" wrote:


                1) we just writing wrapper and trying to workaround all the extension points missed issues. In that case additional coding will be done for that workarounds.


                So this is "we go our own way" and replace everything we need in the easiest way.


                2) we wrinting the same wrapper for JSF mechanism as for first case, but additionally redefining or change some of original script methods in order to get needed extension points. And propose that code to JSF team. After they will apply the changes we could remove it and just use wrapper with extension points we will get.


                This is working with mojarra and planning extension points that we could contribute or propose.

                Obviously I'm for #2 - but would like to know more what we would need to give up. Are there any early features that you don't think will work this way?

                • 5. Re: Ajax Client-side library: ways of implementation
                  jbalunas

                   

                  "nbelaevski" wrote:

                  I guess wrapper will be much more simpler if we get all necessary extension points already included in Mojarra code. Note that this approach will not work with JSF 2.0.0, only with the later versions.


                  Understood. In fact this brings up a good question, what will be needed for us to run assuming we don't get any changes into mojarra or spec?

                  • 6. Re: Ajax Client-side library: ways of implementation
                    nbelaevski

                     

                    "jbalunas@redhat.com" wrote:
                    Obviously I'm for #2 - but would like to know more what we would need to give up. Are there any early features that you don't think will work this way?

                    This point combines #1 with the "clean" approach of using necessary extension points.

                    List of things that will have limited functionality:

                    queue extensions

                    Parallel requests won't be possible - here's what our queuing specification says: "This is because artificial serializing of all ajax requests on a page can significantly effect expected behavior" - so we need to decide whether this was a backward compatibility requirement or necessary feature.

                    "timeout" attribute won't be supported.

                    For the case of new request coming into queue when previous one is not completed: by updated RF queue specification, serialization of form state is done in the moment when request is actually submitted to the server, but JSF (and RF 3.3.x) uses opposite approach - serialization happens when submit function is called. We won't be able to combine both approaches wrapping standard JSF JS API functions by our wrapper functions doing actual queuing. Either RF or JSF specification will be violated.
                    Wrapping JSF JS functions by ours seems to be the only way that guarantees that requests are not reordered (e.g. from f:ajax and delayed from a4j:ajax).

                    addition of external scripts/styles by AJAX request

                    Scripts loading is implemented in Mojarra RI, but it's implemented using synchronous XMLHttpRequest. Practically this means that IE7 loading such script resources from slow server will completely block all user interaction for all tabs until script will be downloaded - even switching between tabs for different sites is disabled. We are using another approach in 3.3.x, but main problem that for using it with RI script is that inline scripts in updated page area should not execute until external scripts are loaded (their readyState="complete") and RI AJAX script doesn't delay execution of inline scripts.
                    Styles loading is not implemented in RI at all.

                    cleanup for DOM elements and components

                    This can be worked around, however for the sake of simplicity component's cleanup should be called before component is removed and new component is created by AJAX, not after that. This requires knowledge of the structure of response from script and has potential issues with 3rd-party libraries and future JSF versions.

                    browser history support

                    This is not investigated much yet, some risks are possible.

                    • 7. Re: Ajax Client-side library: ways of implementation
                      nbelaevski

                       

                      "jbalunas@redhat.com" wrote:
                      "nbelaevski" wrote:

                      I guess wrapper will be much more simpler if we get all necessary extension points already included in Mojarra code. Note that this approach will not work with JSF 2.0.0, only with the later versions.


                      Understood. In fact this brings up a good question, what will be needed for us to run assuming we don't get any changes into mojarra or spec?

                      We can wrap standard JSF functions with our extension functions (physically this means that we load richfaces.js after jsf.js - easy to achieve) and delegate actual functionality to stored original JSF functions. Another thing that we can use is JSF JS events mechanism - it's already involved in A1 for logging (see a4j:log example).

                      • 8. Re: Ajax Client-side library: ways of implementation
                        jbalunas

                         

                        "nbelaevski" wrote:

                        Parallel requests won't be possible - here's what our queuing specification says: <i>"This is because artificial serializing of all ajax requests on a page can significantly effect expected behavior"</i> - so we need to decide whether this was a backward compatibility requirement or necessary feature.


                        Iirc this comment was from the discussion of the global queue and not tied to all requests.

                        In JSF 2 are all requests queued and fired serially?


                        "timeout" attribute won't be supported.

                        So there is no way to abandon a request once made? Assuming the worst and the point above if a single ajax request is stalled on the server it would freeze all interaction - right?

                        For the case of new request coming into queue when previous one is not completed: by updated RF queue specification, serialization of form state is done in the moment when request is actually submitted to the server, but JSF (and RF 3.3.x) uses opposite approach - serialization happens when submit function is called. We won't be able to combine both approaches wrapping standard JSF JS API functions by our wrapper functions doing actual queuing. Either RF or JSF specification will be violated.
                        Wrapping JSF JS functions by ours seems to be the only way that guarantees that requests are not reordered (e.g. from f:ajax and delayed from a4j:ajax).


                        So in this case what is the implication if we follow JSF rule for this one, as was done with 3.3.X?


                        Scripts loading is implemented in Mojarra RI, but it's implemented using synchronous XMLHttpRequest. Practically this means that IE7 loading such script resources from slow server will completely block all user interaction for all tabs until script will be downloaded - even switching between tabs for different sites is disabled. We are using another approach in 3.3.x, but main problem that for using it with RI script is that inline scripts in updated page area should not execute until external scripts are loaded (their readyState="complete") and RI AJAX script doesn't delay execution of inline scripts.
                        Styles loading is not implemented in RI at all.


                        These both seem like spec issues - Alex do you know what happened in this area, or have any insights?


                        • 9. Re: Ajax Client-side library: ways of implementation
                          nbelaevski

                           

                          "jbalunas@redhat.com" wrote:
                          "nbelaevski" wrote:

                          Parallel requests won't be possible - here's what our queuing specification says: <i>"This is because artificial serializing of all ajax requests on a page can significantly effect expected behavior"</i> - so we need to decide whether this was a backward compatibility requirement or necessary feature.


                          Iirc this comment was from the discussion of the global queue and not tied to all requests.

                          This comment has been successfully moved into the article we used as specification and documentation. On of our users asked for clarification/examples when this can affect behavior, but we hadn't provided much information: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=160151.

                          "jbalunas@redhat.com" wrote:
                          In JSF 2 are all requests queued and fired serially?

                          Yes. Also there is no mechanism of "combining" similar events, so such things as f:ajax for "onkeypress" flood server with many requests, that can be still processed long after user has stopped typing.

                          "jbalunas@redhat.com" wrote:

                          "timeout" attribute won't be supported.

                          So there is no way to abandon a request once made? Assuming the worst and the point above if a single ajax request is stalled on the server it would freeze all interaction - right?

                          I guess there should be some kind of communication timeout fallback, but not sure about this. AjaxPatterns.org says that request can be lost forever: http://ajaxpatterns.org/XMLHttpRequest_Call - see "Detecting Errors" section.
                          Mojarra RI script doesn't contain any calls to timer functions.

                          "jbalunas@redhat.com" wrote:

                          For the case of new request coming into queue when previous one is not completed: by updated RF queue specification, serialization of form state is done in the moment when request is actually submitted to the server, but JSF (and RF 3.3.x) uses opposite approach - serialization happens when submit function is called. We won't be able to combine both approaches wrapping standard JSF JS API functions by our wrapper functions doing actual queuing. Either RF or JSF specification will be violated.
                          Wrapping JSF JS functions by ours seems to be the only way that guarantees that requests are not reordered (e.g. from f:ajax and delayed from a4j:ajax).


                          So in this case what is the implication if we follow JSF rule for this one, as was done with 3.3.X?

                          We already discussed that issue: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=160964. The problem touched there is that inputs added to view are not properly decoded.

                          "jbalunas@redhat.com" wrote:

                          Scripts loading is implemented in Mojarra RI, but it's implemented using synchronous XMLHttpRequest. Practically this means that IE7 loading such script resources from slow server will completely block all user interaction for all tabs until script will be downloaded - even switching between tabs for different sites is disabled. We are using another approach in 3.3.x, but main problem that for using it with RI script is that inline scripts in updated page area should not execute until external scripts are loaded (their readyState="complete") and RI AJAX script doesn't delay execution of inline scripts.
                          Styles loading is not implemented in RI at all.


                          These both seem like spec issues - Alex do you know what happened in this area, or have any insights?

                          Here is the list of changes in spec.: http://wiki.java.net/bin/view/Projects/Jsf2MR1ChangeLog that are not yet in the final .PDF. I don't see anything about this point there.

                          • 10. Re: Ajax Client-side library: ways of implementation
                            jbalunas

                             

                            "nbelaevski" wrote:

                            This comment has been successfully moved into the article we used as specification and documentation. On of our users asked for clarification/examples when this can affect behavior, but we hadn't provided much information: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=160151.


                            I'm assuming you are referring to this page correct - http://www.jboss.org/community/wiki/DesignofRichFacesa4jqueue?

                            I'm not sure I understand what you mean by "moved into the article"? The whole reason we did not turn on the global queue by default was to allow parallel requests if the developer wanted it. i.e. leave the option open to developer for choice.

                            Is the problem that JSF 2 will make parallel requests impossible, or force them?
                            Yes. Also there is no mechanism of "combining" similar events, so such things as f:ajax for "onkeypress" flood server with many requests, that can be still processed long after user has stopped typing.


                            That seems like quite the problem - Alex any insight from the spec?

                            In fact all rest of these issues I have the same question :-)


                            • 11. Re: Ajax Client-side library: ways of implementation
                              nbelaevski

                               

                              "jbalunas@redhat.com" wrote:
                              "nbelaevski" wrote:

                              This comment has been successfully moved into the article we used as specification and documentation. On of our users asked for clarification/examples when this can affect behavior, but we hadn't provided much information: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=160151.


                              I'm assuming you are referring to this page correct - http://www.jboss.org/community/wiki/DesignofRichFacesa4jqueue?

                              I'm not sure I understand what you mean by "moved into the article"? The whole reason we did not turn on the global queue by default was to allow parallel requests if the developer wanted it. i.e. leave the option open to developer for choice.

                              It seems to me that the main reason was back compatibility. And I'd suggest to discuss whether we are going to implement support for parallel requests in 4.0. Here is what JSF 2.0 specification ("13.3.2 Ajax Request Queueing") says:
                              All Ajax requests must be put into a client side request queue before they are sent to the
                              server to ensure Ajax requests are processed in the order they are sent


                              • 12. Re: Ajax Client-side library: ways of implementation
                                jbalunas

                                 

                                "nbelaevski" wrote:

                                It seems to me that the main reason was back compatibility. And I'd suggest to discuss whether we are going to implement support for parallel requests in 4.0. Here is what JSF 2.0 specification ("13.3.2 Ajax Request Queueing") says:
                                All Ajax requests must be put into a client side request queue before they are sent to the
                                server to ensure Ajax requests are processed in the order they are sent


                                ic - So if we go with the spec approach we have global serialization.

                                It might be a good "feature" to allow for parallel requests as an option, but as you said might be hard to do and maintain interop.