I'm trying to create a thread at Rails startup which will run throughout the lifetime of the app. The strange thing is, I already had this working with another thread I was running. I copied that (working) code and used it as boilerplate for the new code for the new thread. But the thread won't fire up.
- Code is in config/initializers (is this the correct place?).
- File is named starting with 'z_...' to insure it runs last.
- Rails 3.2.6
Here is the general structure of the code:
class Blah
def self.the_thread
The_Model.transaction do
# do some database stuff
# ...
end
TheThread = Thread.new do
while true do
the_thread
sleep 5.seconds
end
end
end
Opening a rails console and examining Blah::TheThread reveals a dead thread that appears not to ever have run. There don't seem to be any errors in the declaration of the class, nor in the method because I can run the method when I open a rails console and it works just fine. Also, if I manually type into the rails console the exact code above which spawns the thread (TheThread = Thread new do ...), it works just fine (wakes up every 5 seconds, does its thing, sleeps again).
Again, the weird thing is, this exact boilerplate for spawning a simple thread in Rails worked for me before, in this exact same application.
If anyone has some possible insights into what I consider to be a strange problem, I'm all ears.
Thanks.
EDIT: New information - I just commented out the transaction call (and matching end) and it works fine. I don't know what the transaction could be interfering with though. I removed my other custom initializer script, and the only other ones in the directory are either default ones, or one that belongs to devise. I perused them, and didn't see any transactions going on.
More new info. I added 'TheThread.abort_on_exception = true' at the end of the thread code. When I startup rails I now get an exception 'ArgumentError: prepare called on a closed database: rollback transaction (ActiveRecord::StatementInvalid)'. The error is happening in the sqlite3 gem. I have sqlite3 gem version 1.3.6 and sqlite-ruby gem version 1.3.3. I have googled the error and found several posts complaining about the same error, but have not seen any solutions.
I no longer consider this to be a thread problem, but rather a database problem, but too late to change the title of this post.
THIS JUST IN: I put a 'sleep 15.seconds' right at the top of the thread code (just before it goes into the while loop) and that clears the problem up. But I'd still like to know what is causing the problem, and what a 'non-hacked' solution would be. For some reason the database isn't ready when this code runs. Is my initialization code simply in the wrong place?