Reputation: 934
Suppose I have an User model and when I create a new user model, I spawn a new thread that needs to some networking/background tasks after the user has been created.
def create
@user = User.new(params[:user])
collect_info_async(@user)
respond_to do |format|
if @user.save
format.html { redirect_to @user, notice: 'User created.' }
else
format.html { render action: "new" }
end
end
end
def collect_info_async(user)
Thread.new do
logger.info "Thread starting" #Gets logged correctly
#Do some network requests, perform calculations, etc.
usr = User.find_by_id(user.id).update_attributes(:info => gathered_info)
logger.info "Thread finishing"
end
end
When I create a new user, then in the logs I see "Thread starting", but I don't see "Thread finishing" at the same moment when it really finishes. I have to do a User.find from the console or refresh the user page after some time and then I am able to see the "Thread finishing" log. So when does the asynchronous task really finish? And is using a Thread the right choice? I'm using Ruby 1.9.3 and Rails 3.2.8.
Upvotes: 1
Views: 1429
Reputation: 687
At the moment is it better to use a dedicated worker process for background jobs in Rails, instead if using threads. You could use Sidekiq, Resque, delayed_job, etc. RailsCasts have some good screencasts about those.
There is actually a good RailsCast about thread-safety. You need to be a pro member to watch it, however.
Upvotes: 1