PDA

View Full Version : Ability to NOT batch a request?



Dave.Sanders
25 Jul 2009, 8:32 AM
I have a case where I'm loading a Portal page, and each portlet then goes off and asks for its content from the server. I'm converting this from RemoteComponent to an Ext.Direct based model.

I got it all working but realized that my portlets, which are asking for their content via Ext.Direct methods, are being batched up and sent to the server all at once. This makes sense, to keep server traffic down, and my router can handle it (Evan's .Net router) so it all "works", but it could be detrimental to the Portal experience. If one portlet takes a while to load, it holds up all of the others which could come back immediately.

What I'd like to do is, per call, tell Ext.Direct that I don't want it to batch the call with others. This way, I could tell my portlet calls to all go separately and be handled by the server on their own.

Is there a way to do this already and I'm just missing it? If not, is it something we could discuss and possibly add in? Or, is there a different way I should be handling the portlets in this case? (Yes, I know I can go back to RemoteComponent, but if there's an Ext.Direct way to do it, I'd rather do it that way.)

Thanks
Dave

Dave.Sanders
25 Jul 2009, 9:59 AM
Ok, I found the "enableBuffer" property on the provider level. I think this is exactly what I need, BUT it would be nice if this were defined on the method level.

I think what I might end up doing is creating multiple providers, one to contain the non-buffered actions and the other to contain everything else. This will be a bit of a pain because I'll have to further modify the router to be able to handle this, but its doable.

Dave

Dave.Sanders
25 Jul 2009, 10:53 AM
Ok, if anyone on the Ext dev team wants to do this, there here is my suggestion on one way to implement this:

change Ext.direct.RemotingProvider.queueTransaction to


queueTransaction: function(t){
if(t.form){
this.processForm(t);
return;
}
if (t.enableBuffer != undefined && !t.enableBuffer) {
this.combineAndSend();
this.callBuffer.push(t);
this.combineAndSend();
}else{
this.callBuffer.push(t);
if(this.enableBuffer){
if(!this.callTask){
this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
}
this.callTask.delay(typeof this.enableBuffer == 'number' ? this.enableBuffer : 10);
}else{
this.combineAndSend();
}
}
},


And add this line in Ext.direct.RemotingProvider.doCall:


enableBuffer: m.enableBuffer,

in the "var t = new Ext.Direct.Transaction({" section.

Then, if the API provider sends in "enableBuffer:false" on their method declaration, then buffering won't be enabled for that method, regardless of what the provider says.

I'll probably implement this as a UX on my side, but it would be nice if this were in the code properly as an optional feature.

Dave.Sanders
25 Jul 2009, 11:01 AM
And here's the quick and dirty ux if anyone else wants it.


Ext.ux.BufferedProvider = Ext.extend(Ext.direct.RemotingProvider, {
queueTransaction: function(t){
if(t.form){
this.processForm(t);
return;
}
if (t.enableBuffer != undefined && !t.enableBuffer) {
this.combineAndSend();
this.callBuffer.push(t);
this.combineAndSend();
}else{
this.callBuffer.push(t);
if(this.enableBuffer){
if(!this.callTask){
this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
}
this.callTask.delay(typeof this.enableBuffer == 'number' ? this.enableBuffer : 10);
}else{
this.combineAndSend();
}
}
},

doCall : function(c, m, args){
var data = null, hs = args[m.len], scope = args[m.len+1];

if(m.len !== 0){
data = args.slice(0, m.len);
}

var t = new Ext.Direct.Transaction({
provider: this,
args: args,
action: c,
method: m.name,
enableBuffer: m.enableBuffer,
data: data,
cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
});

if(this.fireEvent('beforecall', this, t) !== false){
Ext.Direct.addTransaction(t);
this.queueTransaction(t);
this.fireEvent('call', this, t);
}
}
});

crp_spaeth
27 Jul 2009, 1:37 PM
Very Nice! Thank you for sharing this

evant
27 Jul 2009, 4:11 PM
Seems like a good idea.

elishnevsky
27 Jul 2009, 7:57 PM
Yes, it is definitely a very good idea. I'm thinking it would be okay to let Ext.Direct buffer requests by default unless a request contains an option, that indicates otherwise, like buffered:false. What do you think?

evant
27 Jul 2009, 8:09 PM
I would think the behaviour should be that the request will default to whatever is specified in the provider, unless an option is explicitly defined on the request itself.

elishnevsky
27 Jul 2009, 8:58 PM
I would think the behaviour should be that the request will default to whatever is specified in the provider, unless an option is explicitly defined on the request itself.

Sorry, that's what I really meant :) So are you guys going to make this change in SVN or something?

crp_spaeth
27 Jul 2009, 11:09 PM
+1 for adding this to svn :)

thesilentman
27 Jul 2009, 11:37 PM
Nice! +1

Dave.Sanders
28 Jul 2009, 5:11 AM
There is one downside that needs to be accounted for - it doesn't apply in my particular case, but I think some change in the logic needs to happen for the following.

If you have 5 requests, 2 buffered, 1 not, then 2 more buffered, the code that I posted would create 3 requests. The first 2 would go together, then get cleared out for the third, then the third batch would go. What should really happen is that the unbuffered should just go out on their own, and the buffer should continue to accumulate. I just need to go in and rework it in the code - or hopefully someone on Ext team who knows what they were doing (as opposed to my amateurish attempts) can work it out.

And yes, I think the default should be provider if the method doesn't apply a setting.