Index ¦ Archives  ¦ Atom  ¦ RSS

Enyo - Auto-retry service timeouts

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

© Fahrzin Hemmati. Built using Pelican. Theme by Giulio Fidente on github.