Updater: The Story of a Gem
Thursday
Oct 22, 2009
6:34 pm
The game loop is an essential part of what makes a game work. To implement one for Antares Trader, I wrote a class that would repeatedly call the update method on DataMapper resources. It was a quick hack that got my mini-game sketches working. Eventually, I needed to pull the code out from under the web server and give it it's own process. For a while it was just a class in the lib directory. Eventually, updater grew to need it's own table in the database and now there was Updater code in too many different places.
At this point I went looking for a better solution. I picked up delayed_job and liked what I saw. It did a lot of what I needed. It had a cool API, and GitHub used it so I knew that it had been tested in the real world. On the other hand there were a couple of features missing, and more importantly, it depended on ActiveRecord. So it was back to Updater.
At this point, I decide to pull all the code out and make a Gem out of it. Merb's framework has great support for using gems, and it was a nice clean way to segregate some messy code and put everything in one place. Thus was Updater 0.1.0 born. I never intended to release it into the wild but the more I worked with it the more useful for other projects it became. To make my life easy, I pushed a version to GitHub back when they hosted gems. Just recently I ripped the guts out of the old slow worker class and replaced them with code I lifted from delayed_job. Yea, open source.
I also pushed the gem to Gemcutter. So this is going to serve as a first release announcement. The code is very alpha, but it does work. One can think of this as delayed_job for Datamapper. My one big complaint is that I cannot think of a better name. I took the name form the name of the class I originally wrote, but it is not very descriptive, and I like to find something with more of a 'cool factor.' Suggestions are welcomed to be sent to @antarestrader on twitter.
There are a few things that this version does that delay_job does not and some features of delayed_job I don't implement or do differently.
- No priority. It may be coming but it is low on my list of thing to do.
- No
send_laterAPI. Again on the to-do list but my code all uses my old API so I'm not in a rush. - Can use something besides clock time. This was important to me. I have an internal game clock that I can start and stop. I wrote Updater with the ability to use a class besides Time as its reference. Any object that responds to #now with a value that responds to to_i will work. The
Timeclass is used by default. - Will sleep until the next event. I'm using this on my blog (next release) to clear the cache on posts. It only needs to run once or twice a day. There is really no point polling the poor database every 10 seconds. If a new job comes in the worker can be awakened with SIGUSR1.
I would also like to work on using fork and select instead of the native thread call, but this will have to wait until I can find some time and some help understanding just how to make unix processes talk to each other.