Cleanly Terminating Ruby Daemons
08 05 15
Recently, I have been spending a lot of time working on a daemon written in Ruby. I’m using the Daemons gem as a starting point as it does a nice job of taking care of the nitty-gritty details of spawning threads, dealing with PID files, and providing a simple interface for starting and stopping the daemon. The stopping part, however, has been somewhat problematic for me as the daemon sometimes continues to run. Somewhere along the line the exception being raised is eaten up, never to fulfill its destiny as the mortal messenger that it is.
There’s also the case where you may want certain code to finish executing before the daemon exits. It would be nice to have a little more control over the shutdown process rather than just aborting it mid-stride.
I have found a solution that solves both of these issues. Let’s start by looking at a barebones daemon that will just sit quietly in the background until told to do otherwise.
Daemons.run_proc('sleeper, { :log_output => true }') do
puts 'Started'
loop do
puts 'Sleeping'
sleep 1
end
puts 'Stopped'
end
In this case there shouldn’t be a problem stopping this daemon, but it really doesn’t give us much control over the process. Here’s what the output looks if we start it up and let it run for three seconds:
Started Sleeping Sleeping Sleeping
You’ll notice that “Stopped” is never output, but the daemon is abruptly terminated right inside the loop. To get around this, we can use trap to catch the TERM signal and handle it a little more gracefully.
Daemons.run_proc('sleeper', { :log_output => true }) do
puts 'Started'
run = true
trap 'TERM', lambda { run = false }
while run
puts 'Sleeping'
sleep 1
end
puts 'Stopped'
end
Now our output looks just as it should.
Started Sleeping Sleeping Sleeping Stopped
This allows us to cleanly finish up whatever we’re doing and make a graceful exit.
TallyHoh Launches
08 02 18
Daniel and I have been passionately working on TallyHoh for a while now. It’s an online feed reader at its core, but it has big aspirations to be much more than that. You can “tally” and “folly” items from your feeds to cast votes for them in either a positive or negative light. The votes are use to promote the greatest or most controversial topics of the moment.
For those not familiar with the concept, “feeds” basically provide a way to keep tabs on your favorite sites so you don’t have to visit them everyday to find out if they’ve been updated. Using a feed reader you can then subscribe to multiple feeds at once so you can read all of your blogs and news in one place.
We also made one big opinionated decision when we developed TallyHoh: we’re using OpenID exclusively. If you haven’t heard of OpenID, it’s a technological solution to the problem of user account overload. It lets you use a single account to access all of the sites that you visit. While it hasn’t seen mass adoption yet, it’s gaining a lot of momentum, and we feel confident enough in it to put our full weight behind it.
There’s still a lot to come, but we think TallyHoh has value as it stands today so we’re opening it up to let everyone try it out for themselves. We like the fact that our feeds are always online, and TallyHoh does a good job of keeping track of the things that you’ve read so you won’t see the same content twice.
Try it out, and let us know what you think.
JavaScript Closures by Example
07 12 05
I’ve been working with JavaScript for some number of years now, but today was the first day that I truly made use of closures in an intentional way. I’m in the midst of building a dynamic product finder right now, and one of the requirements is to have a table with rows that are sortable. The problem was, once the rows are sorted, their alternating row colors were no longer alternating, but all mixed up according to the sort order.
The table rows needed to be assigned new, alternating class names. Ruby on Rails has a nice little helper built in called cycle that was written just for this very purpose. It takes an array as an argument, and each time it’s called it returns the next value from the array. I decided that it would be nice to have that functionality in JavaScript for use on the client side, so here’s what I came up with:
var Cycle = Class.create({
initialize: function (values) {
this.index = 0;
this.values = values;
},
next: function () {
if (this.index == this.values.size()) this.index = 0;
return this.values[this.index++];
}
});
This ends up looking like this in use:
var rowClasses = new Cycle(['row1', 'row2']); rowClasses.next(); // 'row1' rowClasses.next(); // 'row2' rowClasses.next(); // 'row1'
That works, but it seems like overkill. Closures to the rescue!
var Cycle = function (values) {
index = 0;
return function () {
if (index == values.size()) index = 0;
return values[index++];
};
};
Now, this behaves differently than the Rails version, but direct duplication wasn’t the intent. Here’s how it works:
var nextRowClass = new Cycle(['row1', 'row2']); nextRowClass(); // 'row1' nextRowClass(); // 'row2' nextRowClass(); // 'row1'
As you can see, the function returned from Cycle gets bound to Cycle’s scope—and thus the value of index—maintaining state between each execution.
A problem arises, though, when we create more than one Cycle: each Cycle ends up sharing the same index. I’ve found that the simplest workaround for this is to define the index as another argument to the function.
var Cycle = function (values, index) {
return function () {
index = index || 0;
if (index == values.size()) index = 0;
return values[index++];
};
};
Now we can create as many Cycles as we want, and each will have it’s own unique index. If you know of a better way to do this, please let me know.
Downtime
07 11 20
Sorry about the recent downtime. The server this blog (and several of my other sites) run on is hosted at a facility that uses a wireless link with a building downtown. It turns out someone else came along and placed a new antenna on top of that building that caused a good deal of interference for that network link, and this has caused the incredible slowness of the site over the past couple weeks. Everything should be back to normal now, which means more posts should be forthcoming.
Commit Message of the Year
07 10 08
Dr Math meets Captain Obvious.
— Jeremy Kemper (aka bitsweat)
Changeset 7798 in the Active Record repository.
Rakefiles and RDocs
07 09 29
After releasing Relax into the open arms of those at BarCampOrlando, I decided it was about time I put together a buildfile for the project. Now, I’ve used Rake plenty as a user over the past few years, but I’ve never spent a lot of time looking into how it actually works. My first goal for a buildfile was to create a gem for Relax. This turned out to be incredibly easy, thanks to the built-in gempackagetask. Here’s pretty much the extent of what’s required to create a working buildfile for packaging gems:
require 'rake/gempackagetask'
spec = Gem::Specification.new do |spec|
spec.name = 'relax'
spec.version = '0.0.1'
spec.summary = 'A simple library for creating REST consumers.'
spec.author = 'Tyler Hunt'
spec.email = ''
spec.homepage = 'http://protoh.com/'
spec.platform = Gem::Platform::RUBY
spec.files = FileList['{bin,lib}/**/*'].to_a
spec.require_path = 'lib'
spec.autorequire = 'relax'
spec.test_files = FileList['{spec}/**/*spec.rb'].to_a
spec.has_rdoc = true
spec.extra_rdoc_files = ['README', 'LICENSE']
spec.add_dependency('hpricot', '>= 0.5')
end
Rake::GemPackageTask.new(spec) do |package|
package.need_tar = true
end
Now, a simple rake gem will scour the source files and bundle everything up into a nice, neat gem.
Since then, I’ve been attempting to hurry the project along to a state more typical of most other Ruby packages, and that means writing RDocs. I’ve read lots of code with RDocs, but I don’t recall ever having written any before. It turns out I really like working with the format, and it seems much cleaner than Javadocs. (I’ll leave the details for another post.)
So, I’ve expanded the Rakefile for Relax slightly to add a task for generating my Rdocs:
Rake::RDocTask.new do |rdoc|
rdoc.title = 'Relax Documentation'
rdoc.main = 'README'
rdoc.rdoc_files.include('README', 'LICENSE', 'lib/**/*.rb')
end
Again, a very straightforward task. The full documentation for Relax is now available on the Relax site.
So that’s where Relax development has been focused for the past few days. One of these days I’ll try to put together a high level overview of the progress accomplished last weekend, and the features included in the first release.
Somewhat coincidentally, I’ll be giving a short talk on Rake as part of the Build Tool Shoot Out at the Adogo meeting on Tuesday.
BarCampOrlando: A Way to Relax
07 09 26
I took (a small) part in BarCampOrlando this past weekend. It was a great deal of fun, and all who attended owe Gregg Pollack et al a debt of gratitude for putting their hearts and souls into this project. The event went largely without a hitch, and could safely be called a roaring success.
Going into the day, I was still undecided as to whether I was going to present. I ended up getting a lot of work done during the afternoon, and threw together a few slides and some examples in order to give a short talk. I spoke during the very last 20 minute time slot in the back room on “Consuming REST Services with Ruby,” which was really just a front for showing off the new library I’ve been writing: Relax. I’m going to try to get some more information and some example code up there soon, but for now you can download the gem and play around with it.
I’m looking forward to the next BarCampOrlando event, and there are some rumors going around that we might see one again in the spring. Doing this semiannually will go a long way towards vitalizing Orlando’s tech community.
Heavyweight Wrapper APIs
07 09 06
As I’ve been developing my Amazon FPS API, I’ve had to make some decisions along the way about how the code should be structured. Right now I’m taking the approach of a central API class that has a method for each action provided by the service. Each action, then, has its own request object, which is used to pass parameters into the API call, and its own response object, which is used to pass back the XML response from Amazon as a Ruby object. This approach sometimes seems more akin to a Java API than a Ruby API, so I’m planning to spend some time down the road figuring out a more Ruby-esque means of interacting with the API.
I’ve also been unsure along the way of whether it really makes sense to use such a heavyweight API. I suppose one alternative would be to make use of some magic to simply generate the request from a hash passed to the API. This seems kludgey to me, and having worked with some APIs in the past that operated this way, I feel that the extra effort to duplicate much of the REST service as Ruby code make a lot of sense. One of my biggest gripes with these sorts of APIs is the usage of action and parameter names from the service directly, as they often don’t follow the typical Ruby naming conventions. This alone is enough to warrant a heavier API for me.
Timely enough, Chad Fowler posted an entry on his blog yesterday about “Writing APIs to Wrap APIs.” His philosophy on the matter seems to mirror mine in a lot of ways, and his point about a wrapper API being less brittle especially resounded with me. It’s always nice to receive validation on your efforts, and even more so when it comes from someone you respect.
That being said, progress has slowed a bit as I’ve been taking some time to extract out some of the layers of the API into a library of their own. Ultimately, this will provide anyone writing a REST consumer API with a simple base from which to start, including the logic to handle the HTTP requests, build URLs with query parameters, and parse XML responses. I’m hoping to have enough of this wrapped up in time for BarCampOrlando to be able to give a short presentation on it.
Adventures in RSpec
07 08 30
For the Amazon FPS API I’m working on right now, I’ve decided to try out the BDD approach to things and write behaviors instead of tests.
Let me first say that I’m not an expert on testing by any means, and while I have a pretty good grasp on the how and the why behind it, I’ve been somewhat slack in the practical application of the philosophy. Case in point: I wrote the majority of the code for the API before writing a single line of tests (other than a script I used to test things out manually).
That being said, I installed the RSpec gem earlier this week and began playing around with some tests for a new class I was working on. The class is used to represent a URL query, and is basically just a simplified hash with a special #to_s.
Here’s an excerpt from the spec:
describe 'A query' do
before(:each) do
@url = 'http://example.com/'
@query = Amazon::FPS::Query.new
end
it 'should be accessible as an array' do
@query[:amount] = 10
@query[:amount].should == 10
end
it 'should convert keys to symbols' do
@query['symbol'] = 'aleph'
@query[:symbol].should == 'aleph'
end
end
It should be pretty clear what’s happening here. We’re defining a set of behaviors for “a query”, and we want to make sure that “a query should be accessible as an array,” and a “a query should convert keys to symbols.” The before block gets execute before :each behavior, just as setup would with your tests.
While there’s truly a beauty to the DSL at work here, even it doesn’t compare to the beauty of being able to generate a specifications list from your behaviors:
A query - should be accessible as an array - should convert keys to symbols - should convert to a query string - should convert parameters to strings - should sort its parameters - should encode its parameter values - should be instantiable with a hash
There’s also a very nice output in HTML.
Overall I’ve been fairly impressed with the ease of use of RSpec. It provides a very simple structure to allow you to clearly define the expected behavior of your application, and makes verifying that behavior a trivial endeavor. I haven’t had a chance to explore all of its matchers yet, but there defeinitely seems to be a lot of power and flexibility to be garnered there.
Also, for those of you in the Orlando area looking to learn more about BDD and RSpec, come check out the next ORUG meeting where Gregg will be giving a talk entitled “How I Learned to Love Testing.”
Amazon FPS in Ruby
07 08 26
The Amazon Flexible Payments Service (FPS) looks like a great addition to the payment services arena, and if it’s anywhere near as popular as their other services have been then this one will surely be a huge success. I’m planning on using it for Monoh as the rates are significantly less than those of both PayPal and Google Checkout, and their API looks like it offers more functionality through a cleaner interface.
When I first started looking into using FPS with Ruby, I downloaded Amazon’s sample code, but was quickly discouraged by the complexity of their sample. My disappointment basically boils down to a deap-seated hatred for SOAP, and when you throw encryption with X.509 into the mix, it just becomes way too verbose for my liking, and doesn’t really fit in with the Rubyist philosophy.
Then I discovered that there’s a REST version of the API available, and offers nearly all of the functionality of the SOAP API. I don’t know why they seem to be hiding the REST capabilities, especially after talking to Brian LeGros and hearing from him that the majority of applications consuming Amazon services are using REST. Every sample they’re provided for FPS uses SOAP, except for a single REST example done with Java of all languages.
So I’ve begun working on a Ruby API for FPS over REST, and things are progressing fairly nice now that I’ve gotten over a silly snag that I had early on in the development. I’ve come up with a clean way to implement each action in the API and still keep things pretty DRY. I’m planning on releasing the API once I get the core of the API wrapped up, and I’ll try to post more about the development process as it progresses.
WebCore Rendering Series
07 08 17
I’ve recently been enjoying a series of articles by Dave Hyatt on the Surfin’ Safari blog about the underpinnings of WebCore rendering. I’ve trudged through his detailed description and accompanying header files (not something I’ve come across since my C days) in the hopes of garnering some insight into rendering technology that might help me as a web developer. This week’s article on positioning has provided just such insight, with its detailed descriptions of each of the position modes available: static, relative, fixed, and absolute. While I’m somewhat familiar with each of these, seeing them drafted out in near-specification form has helped to clarify their differences and intricacies. The first five parts are already up, so I would encourage you to at the very least skim over them. The knowledge gained might just give you an “ah ha” moment of your own.
Sour Cream Doughnut
07 08 13
Oh, where have you been all these years, sour cream doughnut? I have long sought out your dense, moist bite, but why should it have taken twenty-four years for you to reveal yourself to me? The chocolate cake may have been a commensurate substitute, but pales in comparison to the sugary sweetness of your fine flesh. Never has a pastry come along with a taste your equal, and never has it been consumed with such voracious tenacity.
.Mac Revamp
07 05 31
When prompted by criticism of .Mac at the recent D conference, Jobs confessed “I couldn’t agree more, and we’ll make up for lost time in the near future.” It will be interested to see how this pans out.
Read the rest of this entryStarting Fresh
07 05 21
As with most blogs and sites on the Internet, this one has gone through several iterations, and tends to get refreshed on a somewhat annual basis, but this time around I’m taking an entirely new approach to the refresh.
Read the rest of this entryMiranda July
07 05 17
I found a few sites today that I want to share. They all revolve around Miranda July’s world somehow.
Read the rest of this entry