Tuesday, 31 December 2013

(4/4) CFRETRY for ColdFusion

G'day:
I had had this article in draft for over a year, but never got around to writing it. Then Matt Bourke offered an idle challenge to me to write four blog articles before year-end (it's not 8pm in the UK yet, so plenty of time), and I found myself trawling through my draft-backlog for inspiration. I came across this article (well: an earlier version of it), but decided "nah, screw that... I missed the boat on that one, Railo's already done it".

But now I read on Twitter that Steven Neiland is suggesting an enhancement to it... and it's something I had a discussion about the last time I floated this idea for CFML (back in 2010: "<cfretry> / retry")...

First things first, Railo already has a retry construct in CFML:

count = 0;
retries = 5;
try {
    writeOutput("<hr>");
    writeOutput("Count: #count#<br>");
    writeOutput("Above exception<br>");
    throw(type="ForcedException");
    writeOutput("Below exception<br>");
}
catch (ForcedException e){
    writeOutput("Top of CATCH<br>");
    
    if (++count <= retries){
        writeOutput("Before RETRY<br>");
        retry
        writeOutput("After RETRY<br>");
    }
    writeOutput("Bottom of CATCH<br>");
}

writeOutput("After TRY<br>");

I cannot fund any CFML-specific docs for retry... there's nothing in the Railo docs that I can find, but the Ruby docs for retry are OK for it. Basically how it works is that - from a catch block - it returns processing to the top of the try block, simply to try the code again. The idea being the catch code can attempt to remedy the situation that caused the initial exception, and having done so, one might retry the code block. The example above demonstrates, via this very contrived output:



Count: 0
Above exception
Top of CATCH
Before RETRY

Count: 1
Above exception
Top of CATCH
Before RETRY

Count: 2
Above exception
Top of CATCH
Before RETRY

Count: 3
Above exception
Top of CATCH
Before RETRY

Count: 4
Above exception
Top of CATCH
Before RETRY

Count: 5
Above exception
Top of CATCH
Bottom of CATCH
After TRY

In my example there's no attempt at remedial action, but instead it just tries again five times (in vain, as the code is never gonna not throw that exception ;-)

I think this is a cool concept. Yay for Ruby.

However my code there also works around one of the perceived shortcomings of the retry idea... without thinking thinks through, one can easily get into an infinite loop. I have written code here to only try five times, but what if my remedial code was to wait a while until a file might become writeable, or something like that? That situation might never happen. Infinite loop.

Now from my perspective... sure, that's fine. If the situation should only be tried n times before bombing out, then write the code to control that. If however it's legit to simply keep retrying periodically until the (in my example) file becomes writable... then... keeping retrying might be a valid thing to do. At least until the request times out.

TBH, I don't think we really need any hand-holding with this, and if we write code that results in an unexpected endless loop... sucked in. You'll only do it once. Well... occasionally... ;-)

Still, I can also see that there could be a case for having a retry count. And I have now seen on two different forums this requirement be raised, so there might be merit for it. The first time it came around was during... I think... either CF9 or CF10 development. But Adobe never implemented any shape or form of retry, so it is moot. However it's now come up again on Railo's bug tracker: "Enhance new retry tag". I want to put my oar in, but I am unsure of what my oar will be. Some thoughts:
  • no, screw it: write yer own bloody code;
  • it might not be a matter of n number of attempts, so perhaps a condition might be better?
  • Or it is perhaps a solid suggestion which deals with most use cases, and for more complicated ones, one can then "write [one's] own bloody code".
What do you think? I think from a ColdFusion perspective, they should be playing bloody catch-up to Railo, so some votes (if you agree) for 3042554  might not go amiss. But from a Railo perspective... what do you think they should do? Let us know here, but also make sure to go make your presence felt on their bug tracker.

And with that... that's it for this blog for 2013.

--
Adam