Victus Spiritus

home

Practical First Rails Threading Example

01 Jan 2010

Getting a Handle On Threads

Yesterday I wrote briefly about threading in Ruby. Ruby threads don't natively take advantage of multiple processors or cores (this may have changed), but they're a great way to lower wait time on concurrent external delays. This is a non-blocking solution to initiating several API calls simultaneously, and greatly reduces delay, an imperative requirement to web services.

Threading Mulitple Model Calls

On initial creation or update, our User model makes API calls to Twitter, as well as several calls to Zemanta markup and Alchemy Orchestr8. We have shifted from a rapid fire status merged keyword extraction using Orchestr8, to a more object specific, rich semantic entity approach per user status. Once the Twitter streaming API fully opens up we can automatically update known user profiles as well as their associated lists and this will diminish the necessity of rapid response. As we grow, we expect many users to be first time visitors, and we are doing our best to make sure load and processing times are minimal.

Threads in the Controller Were No Go

The next level of threading was for each user of a list. We didn't want to bottleneck response based on well populated user lists, so it was natural to attempt threading for User construction. The Rails controller gave us some issues, and after some reading we discovered that threading and Rails was discouraged in favor of background processes. I moved the calls into the User update keywords method and forced the collapse of threads after they all had been initiated (loop over creation, then loop over joining). Eureka! It loaded list pages much faster but there may be a more desirable solution. We had to be careful with timing the database writes to avoid concurrent calls (still learning about limitations).

Threaded User Construction Is Modular, But List API Gets Everything at Once

An alternative to threaded User creation is to treat lists as a new user. The Twitter API may yield a similar batch data grab, updating all statuses and semantic extraction for them would be identical to single User updates. The tradeoff is that we would lose the connection and history of who an entity came from (something that I'd like to leverage in serendipitous social discovery).

I'd love to hear how others are considering threading with web development and waiting on API calls. Please leave any pro tips in the comment section.

You can email me for code snippets (on my phone at the moment). My email is messel at victusmedia dot com.