Version 2 of retry

Updated 2014-05-24 00:22:25 by samoc

samoc: retry is try more than once.

usage: retry count_var count body ?handler...? ?finally script?

e.g. try a few times to get a message through if the network is busy ...

retry count 3 {

    send_message "Hello"

} trap NetworkBusy {} {}

... or, retry with exponential backoff...

retry count 10 {

    send_message "Hello"

} trap NetworkBusy {msg info} {

    puts "$msg"
    after [expr $count * $count * 100]
}

It might occasionally be useful to retry for all errors:

retry count 3 {

    send_message "Hello"

} on error {} {}

Implementation:

proc retry {count_var count body args} {
    # Retry "body" up to "count" times for exceptions caught by "args".
    # "args" is a list of trap handlers: trap pattern variableList script...
    # The retry count is made visible through "count_var".

    upvar $count_var i
    set traps $args

    for {set i 1} {$i <= $count} {incr i} {

        # Try to execute "body". On success break from loop...
        uplevel [list try $body {*}$traps on ok {} break]

        # On the last attempt, suppress the trap handlers...
        if {$i + 1 == $count} {
            set traps {}
        }
    }
}

AMG: Some more explanation would be welcome. -- samoc sorry about the original unexplained version. Revised version is above.

This code appears to retry an operation a specified number of times, swallowing configurable errors and other such abnormal returns all but the final time, though giving the user the ability to specify the handlers. Your example shows waiting one second between retries.

Is this code intended to dodge a race condition? Maybe find another way to design your system such that the race doesn't exist. -- samoc: This code is intended to deal with interfacing to real-world non-determansim (networks, people, actuators, sensors etc...)