Recently I've been working with service methods that either work or timeout, and timeout usually means just retry. This is mainly because the ajax call inside of them goes to a hit-or-miss web service. So to deal with that I started having my failure handler function call the method again, but then I realized it would eventually get stuck in a loop. When my code started getting that messy, I separated it out into a reusable enyo kind, now you can use it too!
enyo.kind({
name:"RetryService",
kind:"PalmService",
statics:{
lastHandler:0,
},
callWithTimeouts:function(args,data){
var handlerName = this.name+'.handler'+(++RetryService.lastHandler);
var handler = {
name:handlerName,
kind:this.requestKind,
timeoutsSeen:0,
isFinished:false,
failure:function() {
if (this.didTimeout) this.timeoutsSeen++;
if (this.didTimeout && this.shouldRetry()) {
// from this.create
this.didTimeout = false;
this.startTimer();
this.call();
} else {
this.isFinished = true;
this.inherited(arguments);
}
},
success:function(){
if(this.response.error == "asynchronous connection failed"){
this.didTimeout = true;
this.failure();
return;
}
this.isFinished = true;
this.inherited(arguments);
},
shouldRetry:function(){
return this.timeouts && (this.timeoutsSeen < this.timeouts) && (!this.isFinished);
},
finish:function(){
// don't destroy things if we're not actually done
if( !this.shouldRetry())
this.inherited(arguments);
}
};
enyo.kind(handler);
// override the request kind with ours temporarily
this.requestKind = handlerName;
this.call(args,data);
this.requestKind = handler.kind;
},
});
Update 9/21/11 7:33AM: Fixed problem where onSuccess would be called multiple times when timeouts eventually resulted in a success before the garbage collector runs.
Update 9/25/11 4:05PM: Fixed statics issue with inheritance