Eric Hodel
10/5/2007 7:34:00 PM
On Oct 5, 2007, at 12:18 , MenTaLguY wrote:
> On Sat, 6 Oct 2007 02:41:11 +0900, Eric Hodel
> <drbrain@segment7.net> wrote:
>>> I would strongly recommend against using timeout.rb: there is no
>>> way to write robust code with it because it can interrupt the
>>> block at
>>> any (i.e. the wrong) time, defeating normal cleanup/unwinding.
>>
>> Not true. You can always rescue the Timeout::Error and do proper
>> cleanup. It just takes work.
>
> Trivial example:
>
> class Average
> def initialize
> @numbers = []
> @total = 0
> end
>
> # postcondition: @total == @numbers.inject(0) { |a,n| a + n }
> def add(n)
> @numbers.push n
> @total += n
> end
> end
>
> Imagine that your timeout block repeatedly calls Average#add, and
> the timeout exception is delivered to the thread before the second
> statement in Average#add completes. What happens?
>
> Yes, you could rewrite all your code and the libraries it uses to
> pervasively use begin/ensure around every statement to maintain
> invariants at the finest possible granularity, but it obviously
> wouldn't perform well (and is also dependent on thread scheduling
> behavior specific to Ruby 1.8).
When you timeout you cannot be sure of where your calculation
stopped, so you either rescue and cleanup, or you throw out the
results because they did not finish.
Also,
def add(n)
Thread.exclusive do
@numbers.push n
@total += n
end
end
--
Poor workers blame their tools. Good workers build better tools. The
best workers get their tools to do the work for them. -- Syndicate Wars