I know that rails is told to be not thread safe. Does anybody know if that
includes all parts of rails or just some? I'm looking for a way to accept TCP
connections in a separate runner process and want to store/modify
ActiveRecord objects.
In a few examples, I saw that it's common to accept a connection and create a
new (ruby-) Thread to do the communication for each connection. Could I use
ActiveRecord in a thread there, or would that open the risk of a race
condition?
If that doesn't work out, would it be ok to create a single thread to do the
ActiveRecord stuff and let the other threads use it and protect it with a
monitor?
If that's still dangerous, I suppose I have to create a second runner process
for ActiveRecord (a fork()ed one should do, I suppose) and let it accept jobs
by looking for spool files created by the threads of the TCP process. However
this wouldn't be a very nice solution. :-/
Yeah ActiveRecord can work with multiple threads like this if you set ActiveRecord::Base.allow_concurrency = true. One thing to make sure of is to kill the database connection at the very end of each thread before you reap it. This will keep you from getting a too many open connection error. I have experimented and if you start a process and load up ActiveRecord and connect to the db, then you spawn threads, they each seem to get their on db connection that you can kill at the end of the threads life without affecting the other connections.
You may want to look at my plugin BackgrounDRb[1] that is a multi threaded worker pool that uses ActiveRecord in threads for ideas.
Note that you risk deadlock with all adapters except PostgreSQL and Oracle even with a carefully managed thread pool since their underlying API don’t use nonblocking IO. A process pool is safer.
This is a strong poing in favor of top-quality pure-Ruby database drivers: they can cooperate with Ruby’s select to simulate a nonblocking API. Unfortunately, the native bindings are faster and more compatible for general use.