Ruby Threading
Ruby threads are useful, but it’s important to understand the limitations and pitfalls of the current implementation. This post is an attempt to pull together some of the key information from various places on web that helped me get up to speed.
Limitations of Ruby Threads
As explained in the Rubyspec wiki, all Ruby threads are serviced by a single native OS thread. The VM schedules threads by timeslicing at well-defined points in the VM. This means that a single misbehaved Ruby thread could starve out all other Ruby threads (although the timeslicing points are many and hard to avoid), and that Ruby threads don’t take advantage of multiple processors or scale to high-end hardware.
For this reason, applications that care about scale typically create multiple Ruby processes. For instance, a web server might spawn multiple FastCGI worker processes are created rather than relying upon a single mulithreaded server as might happen in Java.
Using Threads with ActiveRecord
If you want to use ActiveRecord from multiple threads, you must include the following call in your code, as described here:
ActiveRecord::Base.allow_concurrency = true
Exceptions in threads
As with other languages, be careful with unhandled exceptions thrown within threads. the default behavior is to silently kill the thread that caused the exception. The Threads and Exceptions section has helpful background. When I started coding a multithreaded crawler, I failed to handle an exception causing all of my threads to eventually die, leaving me scratching my head about what happened to them.
If you set Thread.abort_on_exception = true, then an unhandled exception will cause all threads to terminate. This can be helpful in debugging and making unhandled exceptions really obvious.
No Comments so far
Leave a comment
Leave a comment