Wed Jan 23 13:31:40 IST 2008

configd : the configuration daemon

Reading configuration items is a task that almost every application/utility does. Writing code for all those is stupid. Even writing code once and linking it in leaves the language binding issues open. What encouraged me to write this is a frequently invoked piece of (network) code which ideally would check its configuration for each invocation. The disk I/O seemed unnecessary.

Enter configd - the configuration daemon. Reads configuration items (key=value pairs) for "domains" (applications), and gives them out to anyone who cares to ask over HTTP. Supports HTTP GET/HEAD, with the "domain" and "key" headers, handing out the value as the "value" header in the response. Returns a 404 Not Found if it can't find a value, or a 400 Bad Request if the request is malformed. A SIGHUP to configd makes it re-read the (possibly changed) values from the configuration.

configd is consistent with the Unix Philosophy. A simple tool that does only one job, and does it well.

Although configd advertises configurations, it doesn't stop anyone from using it as a trivial key=value "database" (for a stretched definition of the term). It's HTTP - something that's very well understood and supported, and can scale extremely well behind a load balancer, offering caching and remote configuration.

PUT requests for storing values, and some form of authentication are something that might be added some day, although I don't have the need for them right now.

The Git repository will shortly be online.

Edit: The configd repository is now online.

Something that I thought just now: On the trivial database thread, configd can present a consistent interface, once it implements PUT. Reads are cached, load balanced, yadda yadda. And writes are PUT requests. The backend doesn't matter to the application. One can take out the flat files, and replace it with MySQL (with some type checking at the configd/application end), and the application wouldn't know better. A connection can be equated to a transaction. All PUT requests over a connection are rolled as a transaction. How cool is that?

Also: If you use it as a "database", you cleanly separate the scale layer from the business logic layer. Right now, even prototypes use an SQL backend because people want to scale in the future. There's a lot of DBI/SQL where it doesn't belong. Engineers who write prototypes also write SQL instead of a DBA ("its just a prototype"), which they have to maintain as legacy code/design. All these problems vanish away when you use the simple approach. Engineers don't have to worry about SQL or scale. They can be up and running with a flat file backend which can be changed to SQL without the app noticing. If and when you swap in a real database behind it, SQL queries can be written for the engine by real DBAs (you're scaling this up - its no longer a prototype - it makes sense to assign a DBA for this). To top it all, your *hardware* can do sharding. HTTP load balancers can load balance based on headers - and domains/keys are headers here. The applications need not worry about scaling the database _at_all_.

Posted by gera | Permanent Link | Categories: perl, code | [ 0 ]