1. #1
    Sencha User
    Join Date
    Jun 2007
    Posts
    46
    Vote Rating
    6
    kesteb is on a distinguished road

      2  

    Default A method for queuing Ajax requests

    A method for queuing Ajax requests


    I am using a desktop style environment. This environment can have multiple windows open, each making requests back to the server. Due to some well known issues with multiple pending Ajax requests, a queuing mechanism was deemed desirable.

    First some helper classes. This one implements a simple queue processor.

    PHP Code:
    /*
     * File: Queues.js
     * Date: 11-Sep-2012
     * By  : Kevin L. Esteb
     *
     * This module provides simple queue functionality. It supports
     * FIFO and LIFO based queues. By default it is in FIFO mode.
     *
     * The constructor can be passed the following config:
     *
     *   config = {
     *       fifo: true
     *   };
     *
     *   que = new Ext.ux.queue.Queues(config);
     *
     *   que.enqueue(value);
     *   value = que.dequeue();
     *
     * Where "fifo" can be either "true" or "false". When it is false, the
     * queue is in LIFO mode.
     *
     * ---------------------------------------------------------------------
     *
     *   Queues.js is free software: you can redistribute it and/or modify it
     *   under the terms of the GNU General Public License as published by the
     *   Free Software Foundation, either version 3 of the License, or
     *   (at your option) any later version.
     *
     *   Queues.js is distributed in the hope that it will be useful, but
     *   WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     *   General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with RemoteStorageProvider.js. If not, see
     *   <http://www.gnu.org/licenses/>.
     *
     * ---------------------------------------------------------------------
     *
     */

    Ext.define('Ext.ux.queue.Queues', {

        
    queue: [],
        
    fifotrue,

        
    constructor: function(config) {

           
    config config || {};
           
    this.initialConfig config;

           
    Ext.apply(thisconfig);

        },

        
    enqueue: function(value) {

            
    this.queue.push(value);

        },

        
    dequeue: function() {
            var 
    value null;

            if (
    this.queue.length 0) {

                if (
    this.fifo) {

                    
    value this.queue.pop();

                } else {

                    
    value this.queue.shift();

                }

            }

            return 
    value;

        },

        
    peek: function(pos) {
            var 
    value null,
                
    last this.queue.length 1;

            if (
    this.queue.length 1) {

                if (
    pos 0) {

                    
    value this.queue[0];

                } else if (
    pos last)  {

                    
    value this.queue[last];

                } else {

                    
    value this.queue[pos];

                }

            }

            return 
    value;

        },

        
    clear: function() {

            
    this.queue = [];

        },

        
    count: function() {

            return 
    this.queue.length;

        }

    }); 
    This one implements named queues.

    PHP Code:

    /*
     * File: Manager.js
     * Date: 11-Sep-2012
     * By  : Kevin L. Esteb
     *
     * This module provides a simple queue mamanger for named queues. It is
     * implemented as a singleton. Usage is a follows:
     *
     *    qmgr = Ext.ux.queue.Manager;
     *
     *    qmgr.createQueue('ajax', {fifo: true});
     *    qmgr.addItem('ajax', value);
     *
     *    while (value = qmgr.nextItem('ajax')) {
     *
     *    }
     *
     *    qmgr.deleteQueue('ajax');
     *
     * It also exposes two events:
     *
     *    enqueued - when an item is placed into a queue.
     *    dequeued - when an item is removed from a queue.
     *
     * Both of these events provides the name of the queue that this event
     * happened on.
     *
     * ---------------------------------------------------------------------
     *
     *   Manager.js is free software: you can redistribute it and/or modify it
     *   under the terms of the GNU General Public License as published by the
     *   Free Software Foundation, either version 3 of the License, or
     *   (at your option) any later version.
     *
     *   Manager.js is distributed in the hope that it will be useful, but
     *   WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     *   General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with RemoteStorageProvider.js. If not, see
     *   <http://www.gnu.org/licenses/>.
     *
     * ---------------------------------------------------------------------
     *
     */

    Ext.define('Ext.ux.queue.Manager', {
        
    singletontrue,
        
    mixins: {
            
    observable'Ext.util.Observable'
        
    },
        
    requires: [
            
    'Ext.ux.queue.Queues'
        
    ],
        
    uses: [
            
    'Ext.util.Observable'
        
    ],

        
    queues: [],

        
    constructor: function() {

            
    this.mixins.observable.constructor.call(this);
            
    this.addEvents(
                
    'enqueued',
                
    'dequeued'
            
    );

        },

        
    createQueue: function(nameconfig) {

            if (! 
    this.queues[name]) {

                
    this.queues[name] = Ext.create('Ext.ux.queue.Queues'config);

            }

        },

        
    deleteQueue: function(name) {
            var 
    queue null;

            if (
    queue this.getQueue(name)) {

                
    queue.clear();
                
    delete this.queues[name];

            } else {

                
    Ext.Error.raise('queue "' name '" is not defined');

            }

        },

        
    getQueue: function(name) {

            return (
    this.queues[name] || null);

        },

        
    nextItem: function(name) {
            var 
    queue nullvalue null;

            if (
    queue this.getQueue(name)) {

                
    value queue.dequeue();
                
    this.fireEvent('dequeued'name);

            } else {

                
    Ext.Error.raise('queue "' name '" is not defined');

            }

            return 
    value;

        },

        
    addItem: function(namevalue) {
            var 
    queue null;

            if (
    queue this.getQueue(name)) {

                
    queue.enqueue(value);
                
    this.fireEvent('enqueued'name);

            } else {

                
    Ext.Error.raise('queue "' name '" is not defined');

            }

        },

        
    countItems: function(name) {
            var 
    count 0queue null;

            if (
    queue this.getQueue(name)) {

                
    count queue.count();

            } else {

                
    Ext.Error.raise('queue "' name '" is not defined');

            }

            return 
    count;

        }

    }); 
    This class implements an event driven dispatcher to manage the queued requests.

    PHP Code:

    /*
     * File: Dispatcher.js
     * Date: 11-Sep-2012
     * By  : Kevin L. Esteb
     *
     * This module provides a method to perform queued ajax requests. It is
     * implemented as a singleton. Usage is as follows:
     *
     *    var config = {
     *        pending: 2,
     *        queue: {
     *            name: 'ajax',
     *            fifo: false
     *        }
     *    };
     *
     *    Ext.ux.data.Dispatcher(config).run();
     *
     * Everything after this is event driven.
     *
     * ---------------------------------------------------------------------
     *
     *   Dispatcher.js is free software: you can redistribute it and/or modify
     *   it under the terms of the GNU General Public License as published by
     *   the Free Software Foundation, either version 3 of the License, or
     *   (at your option) any later version.
     *
     *   Dispatcher.js is distributed in the hope that it will be useful, but
     *   WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     *   General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with RemoteStorageProvider.js. If not, see
     *   <http://www.gnu.org/licenses/>.
     *
     * ---------------------------------------------------------------------
     *
     */

    Ext.define('Ext.ux.data.Dispatcher', {
        
    singletontrue,
        
    mixins: {
            
    observable'Ext.util.Observable'
        
    },
        
    requires: [
            
    'Ext.ux.queue.Queues',
            
    'Ext.ux.queue.Manager'
        
    ],
        
    uses: [
            
    'Ext.Ajax',
            
    'Ext.data.proxy.Ajax',
            
    'Ext.util.Observable',
            
    'Ext.data.Connection'
        
    ],

        
    qmgr: {},
        
    count0,
        
    pending2,
        
    queue: {
            
    name'ajax',
            
    fifofalse
        
    },

        
    constructor: function(config) {

           
    config config || {};
           
    this.initialConfig config;

           
    Ext.apply(thisconfig);

               
    this.mixins.observable.constructor.call(thisconfig);

           
    this.qmgr Ext.ux.queue.Manager;

        },

        
    run: function() {

           
    this.qmgr.createQueue(this.queue.name, {fifothis.queue.fifo});

           
    // The processing of the 'ajax' queue is event driven.
           //
           // Observe Ext.data.Connection so that we can respond to it's events.

           
    Ext.util.Observable.observe(Ext.data.Connection);
           
    Ext.data.Connection.on({
               
    requestcomplete:  {
                   
    fnthis.completed,
                   
    scopethis
               
    },
               
    requestexception: {
                   
    fnthis.exception,
                   
    scopethis
               
    }
           });

           
    // Wait for any "enqueued" events and then start processing.

           
    this.qmgr.on({
               
    enqueued: {
                   
    fnthis.dispatch,
                   
    scopethis
               
    }
           });

        },

        
    dispatch: function(name) {
            var 
    request;

            if (
    name === this.queue.name) {

                if (
    this.count this.pending) {

                    if (
    request this.qmgr.nextItem(this.queue.name)) {

                        
    Ext.Ajax.request(request);
                        
    this.count++;

                   }

                }

            }

        },

        
    completed: function() {

            
    this.count--;

            if (
    this.count 0) {

               
    this.count 0;

            }

            
    this.dispatch(this.queue.name);

        },

        
    exception: function() {

            
    this.count--;

            if (
    this.count 0) {

               
    this.count 0;

            }

            
    this.dispatch(this.queue.name);

        }

    }); 
    Now, load order is important. The above needs to be loaded and initialized before the override to Ext.data.proxy.Ajax. I found that the only reliable way to do that is to place everything into one file or use a templating engine to include them all into one request. Since the backend is written in Perl, I can use the Template Toolkit as a preprocessor. Here is the override.

    PHP Code:

    /*
     * Load order is important. This is the only way to ensure that these
     * modules are loaded before the Ext.data.proxy.Ajax override. Otherwise
     * you will get undefined name space errors.
     */

    [% INCLUDE "queue/Queues.js" %]
    [% INCLUDE 
    "queue/Manager.js" %]
    [% INCLUDE 
    "data/Dispatcher.js" %]

    /*
     * Override the default behavior of Ext.data.proxy.Ajax to use a
     * named queue to control the outstanding ajax requests. The queue
     * is processed in a LIFO manner. The "queue" and "fifo" values can
     * be overriden by configuration.
     */

    Ext.override(Ext.data.proxy.Ajax, {

        
    qmgr: {},
        
    queue'ajax',
        
    fifofalse,

        
    constructor: function(config) {

            
    config config || {};
            
    this.callParent([config]);

            
    this.qmgr Ext.ux.queue.Manager;
            
    this.qmgr.createQueue(this.queue, {fifothis.fifo});

        },

        
    doRequest: function(operationcallbackscope) {
            var 
    writer  this.getWriter(),
                
    request this.buildRequest(operationcallbackscope);

            if (
    operation.allowWrite()) {
                
    request writer.write(request);
            }

            
    Ext.apply(request, {
                
    headers       this.headers,
                
    timeout       this.timeout,
                
    scope         this,
                
    callback      this.createRequestCallback(requestoperationcallbackscope),
                
    method        this.getMethod(request),
                
    disableCachingfalse // explicitly set it to false, ServerProxy handles caching
            
    });

            
    this.qmgr.addItem(this.queuerequest);

            return 
    request;

        }

    }); 
    Now to start the processing, you need to place the following code into your applications initialization routine.

    PHP Code:

    var dispatcher Ext.ux.data.Dispatcher;
    dispatcher.run(); 
    Now every store that uses the "ajax" proxy or inherits from the 'ajax' proxy class will be queued.

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    8,917
    Vote Rating
    443
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Seems interesting .. will have to check this out. Thanks.

    Scott.

  3. #3
    Ext JS Premium Member
    Join Date
    May 2008
    Posts
    372
    Vote Rating
    4
    ttbgwt is on a distinguished road

      0  

    Default


    Hi,

    I wired this up and tested but any of my stores that has a proxy that uses POST for reads are not getting called now. Any suggestions?

    Code:
    Ext.define('XYZ.proxy.Tags', {
    
    
        extend: 'XYZ.proxy.Base',
    
    
        alias : 'proxy.proxytags',
    
    
        actionMethods:  {
            create: 'POST',
            read: 'POST',  //<== uses POST for read
            update: 'POST',
            destroy: 'POST'
        },
    
    
        url: XYZ.URL.routerUrl(),
    
    
        constructor: function (config) {
    
    
            var me = this;
    
    
            Ext.apply(me, config);
    
    
            me.callParent(arguments);
        }
    
    
    });

  4. #4
    Ext JS Premium Member
    Join Date
    May 2008
    Posts
    372
    Vote Rating
    4
    ttbgwt is on a distinguished road

      0  

    Default


    Seems to be working now. I had forgot these lines:

    var dispatcher = Ext.ux.data.Dispatcher;
    dispatcher.run();

  5. #5
    Sencha Premium Member
    Join Date
    Jan 2010
    Location
    Vancouver, Canada
    Posts
    133
    Vote Rating
    10
    bogc will become famous soon enough

      0  

    Default


    @kesteb: Did you test your code in ExtJs 4.1.x & 4.2.x?

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi