I have been negligent about blogging, mostly because I have been coding and studying 100 hrs/week. But, I know that I need to take the time to write about what I’m learning.
So, I recently learned to implement background jobs in Sinatra using the Sidekiq gem.
Sidekiq allows you to create “workers”, to which you can allocate tasks instead of forcing the current server process to wait until a task completes.
Sidekiq runs as a server process parallel to your Ruby application. You send the sidekiq process “work” to do, which gets added to a Redis queue and allows your main program to continue uninterrupted until the workers have finished completing their assigned task.
Here’s an example: I created a web application that allows a user to log in and send tweets through their account using OAuth and the Twitter API.
Before background jobs were implemented, a user would have to wait until the app received confirmation from Twitter (via the API) that the tweet was sent before he/she could send a new Tweet.
Now, in theory, this UX lag problem could have been resolved on the front end using AJAX but that wouldn’t fix the problem of the server process having to pause while each request was sent to Twitter.
Sidekiq to the rescue
In my user model, I added a tweet method:
This inserts a new tweet in the database and then passes the id of this tweet to a
TweetWorker (the Sidekiq/Redis process/queue).
TweetWorker has a
perform method which houses the workers task. In this case, the worker looks up the tweet text from the database and proceeds to update the user’s twitter status via the Twitter
Notice that the
tweet.id, not the tweet object, is passed to the Sidekiq process. This is because whatever gets passed to the worker is added to the Redis queue, which should only hold standard data types, not serialized objects.
I learned a lot from this exercise and am continuing to dive deeper into Redis and background jobs. I know a solid understanding of these topics is necessary for building scalable applications.