- Optimized for a read-heavy workload (config stays the same for months).
- Hierarchical structure (by data center, by server group, by specific host if necessary).
- Queryable at any level.
Tuesday, September 10, 2013
The Forgotten Gem: LDAP
I keep wanting a "configuration lookup service" with the following properties:
Saturday, September 7, 2013
Pen and Paper
One of the surprises I had when I wrote some golang code was that static typing was a real bear to wrestle with again. Once I had the type errors sorted out, though, programs ran fairly well. By the time I could get it past the compiler, I had been forced to think about it deeply enough that there were far fewer bugs in the final result.
Of course, it's not magic. My code has still deadlocked.
The mindset that Go enforces, by virtue of checking the types, has led me to try being more careful in my regular work. I now try to make notes on everything that I need to come back to as I'm exploring a problem (such as: "what code interacts with this variable?") so that I can check my plan against all relevant cases. Likewise, a multi-step change will end up with a few bullet points like...
For complex issues and solutions, doing the design on paper has an extra benefit. Paper encourages brevity. There's only so much room within the confines of a page, and it takes a while to write. Consequently, pseudo code tends to stay pseudo code, at an appropriate level of abstraction, when writing out steps. It's the exact opposite of the temptation to switch to writing the real code when trying to write pseudo code in a text editor. It looks like a convenient shortcut to combine the two coding steps, but then the faults in the overall plan don't get noticed until (often) most of the way through—then a random amount of already-written code is made irrelevant or wrong.
Modifying half-implemented approach A to become approach B (hopefully not with the same last-lap change of course) adds a lot of mental state to juggle. Now there are four states complected: original code, usable code from A, unusable but not yet changed code from A, and code from B. It can be quite useful, and a bit simpler, to work out some of those false starts in advance, on paper. Then there's both a record of where my thoughts have been, and a clean body of current code to implement the final result.
As useful as paper can be, there are also times when it's at a disadvantage. For picking apart tricky, complex control flow with nested ifs, repeated conditionals, and the like, I find it easiest to copy the code into a new window and then start deleting lines and replacing them with pseudo-code comments. Often, hundreds of lines can be reduced to a single window, which makes it trivial to get a higher-level overview of what's being accomplished.
Paper's other major disadvantage is that it lacks undo. I've learned by the number of cross-outs on the page just how frequently I rename things as I get a better sense of the problem and what those parts represent in the whole. (I have even been known to choose a name, cross it out in favor of an alternate, then cross out the alternate to restore the original.)
Overall, though, for the appropriate tasks, it's been a great advantage these past few months to put more effort into paper and less into backtracking in vim.
Of course, it's not magic. My code has still deadlocked.
The mindset that Go enforces, by virtue of checking the types, has led me to try being more careful in my regular work. I now try to make notes on everything that I need to come back to as I'm exploring a problem (such as: "what code interacts with this variable?") so that I can check my plan against all relevant cases. Likewise, a multi-step change will end up with a few bullet points like...
EmailBounce (#3351)This also helps in event of interruptions, such as realizing the office manager's radio is playing the same annoying pop songs again today, for the 110th day in a row. There's a list of stuff to help re-establish concentration, knowing I'm not forgetting anything.
- set in SES bounce processor
- clear when email changes
- react in notifier code
For complex issues and solutions, doing the design on paper has an extra benefit. Paper encourages brevity. There's only so much room within the confines of a page, and it takes a while to write. Consequently, pseudo code tends to stay pseudo code, at an appropriate level of abstraction, when writing out steps. It's the exact opposite of the temptation to switch to writing the real code when trying to write pseudo code in a text editor. It looks like a convenient shortcut to combine the two coding steps, but then the faults in the overall plan don't get noticed until (often) most of the way through—then a random amount of already-written code is made irrelevant or wrong.
Modifying half-implemented approach A to become approach B (hopefully not with the same last-lap change of course) adds a lot of mental state to juggle. Now there are four states complected: original code, usable code from A, unusable but not yet changed code from A, and code from B. It can be quite useful, and a bit simpler, to work out some of those false starts in advance, on paper. Then there's both a record of where my thoughts have been, and a clean body of current code to implement the final result.
As useful as paper can be, there are also times when it's at a disadvantage. For picking apart tricky, complex control flow with nested ifs, repeated conditionals, and the like, I find it easiest to copy the code into a new window and then start deleting lines and replacing them with pseudo-code comments. Often, hundreds of lines can be reduced to a single window, which makes it trivial to get a higher-level overview of what's being accomplished.
Paper's other major disadvantage is that it lacks undo. I've learned by the number of cross-outs on the page just how frequently I rename things as I get a better sense of the problem and what those parts represent in the whole. (I have even been known to choose a name, cross it out in favor of an alternate, then cross out the alternate to restore the original.)
Overall, though, for the appropriate tasks, it's been a great advantage these past few months to put more effort into paper and less into backtracking in vim.
Thursday, September 5, 2013
Moose Alternatives
Wednesday, September 4, 2013
More FastCGI: Apache 2.4, PHP-FPM, PSGI, and hot deployment
Driven by mod_fcgid's failings at graceful restart and preforking, I've been looking hard for alternatives.
php-fpm ships with an init script and reloads gracefully via SIGUSR2, so that's all you really need there.
For Perl, gracefully restarting an FCGI app is difficult, so the better approach for PSGI apps is to run them in an HTTP server with Server::Starter support (e.g. Starman or others).
tl;dr
External FCGI is best done via mod_fastcgi on Apache prior to 2.4, or mod_proxy_fcgi on 2.4. mod_proxy in general is super awesome on 2.4.php-fpm ships with an init script and reloads gracefully via SIGUSR2, so that's all you really need there.
For Perl, gracefully restarting an FCGI app is difficult, so the better approach for PSGI apps is to run them in an HTTP server with Server::Starter support (e.g. Starman or others).
Sunday, August 11, 2013
Pre-compiling Twig Templates
To be able to use option
The next obvious question is, "How do I make twig compile templates without rendering them?" and it turns out there's a simple answer. The long form
Conceptually, then, it's dead simple: configure Twig how you normally would, list out all your template files, and call
'auto_reload'=>false in production with Twig, I need to be able to force a recompilation. The easy way would be to clear the cache directory in the deployer when pushing an update, but if I'm micro-optimizing, why not ship built templates as part of the distribution?The next obvious question is, "How do I make twig compile templates without rendering them?" and it turns out there's a simple answer. The long form
$twig->loadTemplate("name.twig")->render($vars) is the secret: loadTemplate writes to the cache if caching is enabled when the template is loaded.Conceptually, then, it's dead simple: configure Twig how you normally would, list out all your template files, and call
$twig->loadTemplate() on each of them. I believe the minimal solution on POSIX platforms would look like this:Wednesday, August 7, 2013
Smarty vs. Twig (a benchmark done poorly)
Note added 14 Feb 2014: I ended up settling on Twig without too much more rigorous testing. This used to be titled "Part 1" but there is, and is never expected to be, a Part 2. Now back to your original post....
I'm pretty cranky about what my templates do (I have been known to roll my own), so I have a small list of must-have features. Listing in order by increasing likelihood that a template engine satisfies them:
With that, it looks like the contenders are Smarty and Twig, currently at versions 3.1.14 and 1.13.2, respectively. How do they compare in a benchmark showdown?
I'm pretty cranky about what my templates do (I have been known to roll my own), so I have a small list of must-have features. Listing in order by increasing likelihood that a template engine satisfies them:
- Extensible functions for adding convenience from the host environment
- Built-in functions for date formatting
- No annoying
<? ?>all over the place - Auto-escaping of variables when building HTML
- Conditionals, expressions, and loops (if-elseif-else chains, boolean logic)
- Access to array elements and object properties
cycle, for hopefully obvious reasons.)With that, it looks like the contenders are Smarty and Twig, currently at versions 3.1.14 and 1.13.2, respectively. How do they compare in a benchmark showdown?
Thursday, August 1, 2013
Working from Home
Since I've radically changed my work VM configuration, I needed to change my home PC in order to connect properly to the new setup.
Before we dive in, a brief review of the old setup: the host at work, which we will call `audia`, ran a VirtualBox guest named `dev`. dev had its own set of configs and configuration knobs so that I could write
This all changed when I wanted to test a SAN certificate and some redirection rules. I didn't want certificate mismatch errors in Firefox, and I needed dev to think it was the production server so that it would use the production ruleset. That became the underlying justification for devproxy. After that point, dev had the production certificates, hostnames, and rules. It had a host-only network added, which audia now used, and I took out the port forward. (This was the problem behind getting Lost in the Complexity.)
But without the port forward, starlet can't reach dev anymore, only audia. Of course, I came up with a solution:
(Despite what may be implied, the VPN isn't connected to starlet. I just didn't feel like redrawing the whole tube.)
Before we dive in, a brief review of the old setup: the host at work, which we will call `audia`, ran a VirtualBox guest named `dev`. dev had its own set of configs and configuration knobs so that I could write
127.0.0.1 dev.audia.pc dev into /etc/hosts, point Firefox to dev:10080, and code running on dev would be able to recognize "this is development," not require TLS, and know that http://dev:10080/ is the URI root of the app. I configured VirtualBox's port forwarding to listen on 0.0.0.0 from audia, and when I connected to the VPN, my home computer (call it `starlet`) had its own /etc/hosts listing that used the internal IP of audia for dev. The same URI from home would then get connected via port-forwarding to the dev VM.This all changed when I wanted to test a SAN certificate and some redirection rules. I didn't want certificate mismatch errors in Firefox, and I needed dev to think it was the production server so that it would use the production ruleset. That became the underlying justification for devproxy. After that point, dev had the production certificates, hostnames, and rules. It had a host-only network added, which audia now used, and I took out the port forward. (This was the problem behind getting Lost in the Complexity.)
But without the port forward, starlet can't reach dev anymore, only audia. Of course, I came up with a solution:
(Despite what may be implied, the VPN isn't connected to starlet. I just didn't feel like redrawing the whole tube.)
Subscribe to:
Posts (Atom)
