Reputation: 1878
I'm trying to run a process in a thread, and if it takes longer than x seconds, redirect to a waiting page and then do an ajax refresh
begin
Timeout::timeout(10) do
t = Thread.new do
begin
output = do_work
session[:result] = "done"
rescue Exception => e
session[:result] = "exception"
end
end
t.join
end
if session[:result] = "done"
redirect_to :done
else
redirect_back fallback_location: :root, notice: 'Unable to process request, please try again.'
end
rescue Exception => e
if e.message == "execution expired"
# this means the timeout fired, so send them to waiting
redirect_to waiting_path
else
redirect_back fallback_location: :root, notice: 'Unable to process request, please try again.'
end
end
then, in waiting, check for result
def waiting
# session[:result] never updates
end
What am I doing wrong? I would expect that if the exception fires, the thread would survive, as evidenced by this simple experiment:
begin
Timeout::timeout(1) do
t = Thread.new do
sleep(5)
puts "done!"
end
t.join
end
rescue Exception => e
if e.message == "execution expired"
# this means the timeout fired, so send them to waiting
puts "expired!"
end
end
The above code works fine, and after 5 seconds, the thread completes and shows the output.
Is this because you can't set the session in a thread, or something like this?
Thanks for any help, Kevin
Upvotes: 1
Views: 400
Reputation: 11797
You could try passing the current binding to the thread as an argument:
Thread.new(binding) do
thread_session = eval("session", binding)
end
Note: I would suggest to use DelayedJob
which is better way to handle a long-running process spun off from a user request?
Upvotes: 1