Brad Fitzpatrick (brad) wrote,
Brad Fitzpatrick
brad

BML config system rewrite

When I started working on the memcache website, I started to use BML, but then realized it's a pain, due to all the webserver configuration you have to do. It sucks for the same reason mod_perl sucks... great for large websites, terrible for small, quick projects.

One of the things I like about PHP (and there aren't many) is that you can take some files, plop them into a directory, and things work.

With mod_perl it tends to be a pain, involving httpd.conf settings/handlers, pre-loading modules, etc.

I hide all that crap from people installing LJ on their own machines by making one script do the rest of the config, but there's still that one line. You can't just put all the LJ server files in a directory without restarting.

BML's the same way. All the configuration is global, and done in historical, weird places. (we used to support FastCGI, bleh) So it works for huge websites, but it's just not worth it for small ones. And you can't make a self-contained BML site.

When I tried to run FotoBilder and LiveJournal on the server, weird things happened. Global configs fighting. So I added this hacky idea of a "current domain", and all global settings were keyed by that. It was a quick fix, but made things even uglier.

The little memcached website (under 10 pages) has enough things I want to template and can't be done with CSS that I've decided to rewrite BML's config system.

I thought it'd be a quick, little project, but that was just wishful thinking.

With the new system, there are no global config settings. Config files go in directories (_config.bml) and can include other config files, including perl scripts which can use the API to conditionally register config settings, and things bubble up to the document root. I cache the parsed results of each config file, and don't re-stat the file within 10 seconds.

I also have to continue to support parents overriding child configurations, so when I give less-trusted parties/groups access to subdirectories, they can't execute code in BML that isn't part of trusted templates.

And since untrusted directories could load evil Perl, there's an httpd.conf directive to disable reading configs in certain directories. (I figured this is a rare case, so having a directive in httpd.conf is okay... it doesn't the hinder the general "plop files here" solution.)

My next step (while I'm at it) is cleaning up the global.look/generic.look crap. A bunch of BML features were added in the early days that are no longer used, so I'm cleaning it up, simplifying/slimming it for the things it's best at. Instead of the user/system specifying a scheme and then BML looking at a bunch of files to put together the scheme, BML will look at one file, and that file has to include parents, if it wants them.

So, I'm redesigning both the config parsing/loading and the template parsing/loading.

But things get complicated because on LJ we have a VarInitScript which modifies both the config and registers template elements. So that's split into two files. That same file also preloads a ton of modules before the fork, but we already have a new file for that, since mod_perl days (ages ago), so I merged those.

Cleanup, cleanup, cleanup.

Config stuff is done. I'm just starting the template loader changes, but I think I'll sleep instead.

When I'm done, though, I'll be able to make little self-contained BML websites, and smile knowing the code is all clean and properly designed. :-)
Tags: perl, tech
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 8 comments