6 Replies Latest reply on Sep 22, 2009 9:42 AM by ilya_shaikovsky

    Improve queue system to solve some use case

    ronanker

      HI !

      I have a complex issue with queued request that become invalid and i don't know how can i solve it without changing the way queues works :

      the use case :

      in a page i have a form in wich i choose objects to be added on a list that is on an other form with a 'save' button.

      in the list, each object shows its properties editable.

      when i click on my items to add them in the list i have ignoredupresponse and send once the request to add objects in the list and rerender on the list.

      if during this request i click on 'save button' it's added to the queue and executes when the first finish but the content of the form that's sent in the request doesn't contains those inputs that have just been added by first request. and then on the server it saves 'null' value in all my objects overwriting their defaults values...

      note that if i rerender the page then user see all objects empty, if not then user may just exit the page without knowing what he saw wasn't what have been saved...
      if one of the inputs is required, the user gets a message saying it's not set but can see a value in it...
      etc...

      do you understand my problem ?

      a way to solve it :

      I think, it's not the 'serialisation' of the request that should be in the queue but (how to say) the parameters that permit to construct the request :

      here is what you do :

      A4J.AJAX.Submit = function( containerId, formId, event , options ) {
       var domEvt = A4J.AJAX.CloneEvent(event);
       var query = A4J.AJAX.PrepareQuery(containerId, formId, domEvt, options);
       if (query) {
       var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options, formId);
      
       if (queue) {
       queue.push(query, options, domEvt);
       } else {
       A4J.AJAX.SubmitQuery(query, options, domEvt);
       }
       }
      
       return false;
      };

      and here is what i think we could do :
      A4J.AJAX.Submit = function( containerId, formId, event , options ) {
       var domEvt = A4J.AJAX.CloneEvent(event);
       var futureQuery = A4J.AJAX.futureQuery(containerId, formId, domEvt, options);
      
       var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options, formId);
      
       if (queue) {
       queue.push(futureQuery, options, domEvt);
       } else {
       var query = A4J.AJAX.PrepareQuery(futureQuery);
       A4J.AJAX.SubmitQuery(query, options, domEvt);
       }
      
       return false;
      };

      and when poping the futureQuery from the queue then prepare it (var query = A4J.AJAX.PrepareQuery(futureQuery);)
      where futureQuery is only a simple container for containerId, formId, domEvt and options.

      i've thought about this change since RF-3.3.0 for several other use cases, but now i think it become more and more interesting.

      doing that make the execution of the 'onsubmit' of the form occuring just before sending the request, it's really better for my use case. In current code it's executing at the time it's put in the queue, and that's not what i want.
      If we want to execute something when the request is put in the queue, we should have a "onPushedInQueue" attribute on the form.

      Maybe you have use cases where your code is better, so, the best is to have some parameters to choose whether request have to be constructed at 'queue.push' or at 'queue.pop'.

      Thanks in advance for the time you'll send thinking about that and replying me.

      (if you aggree and if you can do it for 3.3.2, you're really the best but if you plan it only for 4.0, i won't blame you, i know you've got lots of work)


        • 1. Re: Improve queue system to solve some use case
          nbelaevski

          Hi Ronan,

          Here is something we were basing on: http://www.jboss.org/community/wiki/DesignofRichFacesa4jqueue - see "View Changes and requests waiting in queue".

          • 2. Re: Improve queue system to solve some use case
            ronanker

            Hi !
            I've read the doc and also all previous discussions about queues, and i think my use case is not treated before.
            for sure it concerns the "View Changes and requests waiting in queue" paragraph, but it requires a third solution for this.

            2.1) We will not collect the events in the queue only as it was before. We will generate the request info right after event and put the complete generated request to the queue. In this case actual form information will be sent with the request.

            that is actual design.

            2.2) We plan to introduce one more common attribute which should allow to define the components which should reset the queue (resetQueueAfterRequest).

            that is future usefull idea.

            and we should add someting like :

            2.3) We will collect the containerId, formId, domEvt and options in the queue, (eventually have some tests at that time), and then generate the request when it's time to send the request.

            -------
            we use one global queue for all
            In our case we don't want to drop any request we just want to execute both requests like if the user had waited before clicking.

            if we construct the request before having updated the dom from the first request then the form sent is no longer synchronized with JSF view.

            I don't know if what i say is clear.

            -------
            it's also possible that i mis-understood queues system, the folowing code can replace what i said before and maybe can help you understand what i think... :

            A4J.FutureQuery = function(containerId, formId){
             this._formId = formId;
             this._containerId = containerId;
             this._query = null;
            };
            A4J.AJAX.PrepareFutureQuery = function(containerId, formId, domEvt, options) {
             //TODO test before push in queue (exemple :)
             //if (option.onPushedInQueue == function){
             // if (!option.onPushedInQueue(containerId, formId, domEvt, options)) {
             // return null;
             // }
             //}
             var futureQuery = new A4J.FutureQuery(containerId, formId);
             if (!option.constructOnDequeue) {
             //we have to construct query imediately
             var query = A4J.AJAX.PrepareQuery(containerId, formId, domEvt, options);
             if (query) {
             futureQuery._query = query;
             } else {
             //if the query can't be constructed then drop
             return null;
             }
             }
             return futureQuery;
            }
            A4J.AJAX.GetQueryFromFutureQuery = function(futureQuery, domEvt, options){
             if (futureQuery._query){
             return futureQuery._query;
             }else{
             //this can return null :
             return A4J.AJAX.PrepareQuery(futureQuery._containerId, futureQuery._formId, domEvt, options);
             }
            }
            A4J.AJAX.Submit = function( containerId, formId, event , options ) {
             var domEvt = A4J.AJAX.CloneEvent(event);
             var futureQuery = A4J.AJAX.PrepareFutureQuery(containerId, formId, domEvt, options);
             if (futureQuery) {
             var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options, formId);
             if (queue) {
             queue.push(futureQuery, options, domEvt);
             } else {
             var query = A4J.AJAX.GetQueryFromFutureQuery(futureQuery, domEvt, options);
             if (query){
             A4J.AJAX.SubmitQuery(query, options, domEvt);
             }
             }
             }
             return false;
            };

            note that this code may not work and is maybe badly writen as I'm not a javascript expert.

            i haven't looked yet the dequeue method, but i think it just have to use "A4J.AJAX.GetQueryFromFutureQuery(futureQuery, domEvt, options);" instead of "query" and test nullity...

            • 3. Re: Improve queue system to solve some use case
              nbelaevski

              Yes, we've missed such use case. Thank you much for pointing to the problem! I've linked this thread to the queue discussion thread: http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4254545#4254545. Please let us some time to discuss that.

              • 4. Re: Improve queue system to solve some use case
                ronanker

                ok, thank you !

                • 5. Re: Improve queue system to solve some use case
                  nbelaevski

                  Hi Ronan,

                  We've discussed the fix version for this problem and decided to postpone this for 4.0.x, because of the significant amount of work required to discuss, develop and test the fix.

                  As a workaround, "process" attribute that takes the value from request parameter can be used, however this doesn't seem very convenient and secure and seems it doesn't allow to mimic "onsubmit" event using queue attributes.

                  • 6. Re: Improve queue system to solve some use case
                    ilya_shaikovsky

                    RonanKER, after further discussion we decided that probably changing the default way to the one you suggested is better way.

                    And we can't currently find the case where it could broke some other cases functionality. Actually we think that in any case collecting view information before sending actual request is much more better from server-client synchronization point of view.

                    Anyone who has some additional thoughts on this RFC please comment there.

                    http://www.jboss.org/community/wiki/DesignofRichFacesa4jqueue