From: "Berger, Daniel" Date: 2005-07-30T00:22:46+09:00 Subject: Re: Allow retry to take arguments? > -----Original Message----- > From: Jim Weirich [mailto:jim@weirichhouse.org] > Sent: Friday, July 29, 2005 9:09 AM > To: ruby-talk ML > Subject: Re: Allow retry to take arguments? > > > > Austin Ziegler said: > > One problem that I see, Jim. In Daniel's pseudo-code, he can rescue > > specific exceptions: > > > > begin > > connect_to_something > > rescue NetworkBusyException, TimeoutException > > retry(3, 30) or raise > > rescue NetworkUnavailableException > > retry(5, 60) or raise > > end > > Gah! What is the semantics of that? What if you get a > NetworkBusyException, so you want to retry 3 times. But the > next time you get a NetworkUnavailable exception. Do you > leave it at 3 retries or up it to a max of 5 tries. Or do > the tries for each exception count individually, i.e. we > could have up to 8 retries, 5 for Unavailable and 3 for > Busy/Timeout. Or is a a max of 11 retries because retries > for timeout and busy count together. That's something that would have to be worked out. There are two approaches I would prefer. The first is that it resets itself whenever the exception changes. So, on the first attempt let's say a NetworkBusyException occurs. On the next attempt a NetworkUnavailableException occurs. In that scenario the number of retries for NetworkBusyException is reset to 3. This seems logical to me, but also runs a greater risk of infinite loops. The second approach is that it's the total number for each exception. So again, on the first attempt let's say a NetworkBusyException occurs, and the number of retries is reduced to 2. On the next attempt a NetworkUnavailableException occurs. The total number of retries for NetworkBusyException remains 2, and the number of retries for NetworkUnavailableException is now 4. On the next attempt a NetworkBusyException happens again, reducing the number of retries to 1, and so on. This also seems logical to me, and avoids the risk of infinite loops. However, I suspect the implementation would be more difficult. > > Yours just allows for one attempt wrapper and doesn't specify what > > sort of exceptions can be caught. > > So use ... > > attempt([NetworkBusyException, TimeoutException] => [3,30], > NetworkUnavailableException => [5, 60]) do > connect_to_something > end > > or something like this ... > > Attempt = RetryController.new do |retry| > retry.on NetworkBusyException, TimeoutException, > :trys=>3, :timeout=>30 > retry.on NetworkUnavailableException, :trys=>5, :timeout=>60 > end > > # ... later in code ... > > Attempt.call { connect_to_something } > > All still doable without changing the language. True, but it just doesn't look nearly as clean. :) Regards, Dan