Retrying to send message

Cecil Westerhof Cecil at decebal.nl
Wed Jun 3 12:15:16 EDT 2015


Op Wednesday 3 Jun 2015 15:29 CEST schreef Chris Angelico:

> On Wed, Jun 3, 2015 at 10:27 PM, Cecil Westerhof <Cecil at decebal.nl> wrote:
>> def send_message(account_id, message, max_tries,
>> terminate_program): error_msg = 'Something went wrong with: ' +
>> message not_send = True tries = 0 while not_send: try:
>> Core().update_status(account_id, message) except
>> libturpial.exceptions.ServiceOverCapacity: tries += 1 print('Tried
>> to send it {0} times'.format(tries)) if tries >= max_tries:
>> terminate_program(error_msg) time.sleep(60) except:
>> terminate_program(error_msg) else: not_send = False
>>
>> Is this a reasonable way to implement this, or is another way
>> better? Well, maybe the timeout should be a parameter also. ;-)
>
> I'd skip the not_send flag and do the logic thusly:
>
> while True:
> try:
> update_status as above
> break
> except ServiceOverCapacity:
> as above

Yes that is much better. I now made it:
    def send_message(account_id, message, max_tries, give_error, wait_time = 60):
        error_msg   = 'Something went wrong with: ' + message
        tries       = 0
        while True:
            try:
                Core().update_status(account_id, message)
                break
            except libturpial.exceptions.ServiceOverCapacity:
                tries += 1
                print('Tried to send it {0} times'.format(tries))
                if tries >= max_tries:
                    give_error(error_msg)
                    return
                time.sleep(wait_time)
            except:
                give_error(error_msg)
                return

> And I'd also skip the bare except clause. If you get any sort of
> exception, whether it's a bug, a failure from libturpial, a network
> error, or anything else, your code will just terminate with a bland
> and useless message. Much better to simply let the exception bubble
> up.

I kept the except. I like to see the message that went wrong. ;-)

Also, in my case give_error terminates the program, but it never hurts
to make functionality generic, so I added return statements. Not
break, because on error you should leave the function. Break would in
this instance do the same, but I find this neater.


>> Also the documentation of time.sleep says:
>> The actual suspension time may be less than that requested because
>> any caught signal will terminate the sleep() following execution
>> of that signal’s catching routine.
>>
>> My program does not much else as sending the message. So I think it
>> is not necessary to cover for this possibility. Are I assuming to
>> much?
>
> I wouldn't worry too much about a signal cutting your sleep short;
> it doesn't look to me as if "exactly sixty seconds" is all that
> crucial here. If your program sleeps for 42.645 seconds and then
> gets woken up by a signal, and you retry a bit sooner than you
> otherwise would have, is it going to break anything? If not, just
> ignore that possibility.

Correct, so I did not assume to much. :-D

Usually I check parameters. But I understood that is not the Python
way. For example a wait_time of 1, or negative is not useful. Also a
max_tries of 10 ** 12 would not be very useful. But I can put the
burden of the problem on the caller of the function?

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof



More information about the Python-list mailing list