2011/01/21

Perl signals and fork aren't safe.

My very first Perl bug ever!

Long story short: there is a race condition between the safe signal handlers (which just update a flag) and pp_fork() invokes the system fork(). No, pp_fork() doesn't reset all the flags, so the signals could be dispatched in the child process, even if they were meant for the parent.

What boggles me is that this bug is easily over 10 years old. I find it hard to believe that no one noticed it before. Of course, it will take a while for a patch to make it into perl. And all the perls installed out their still have the bug.

The work around is to block signals, fork(), then unblock signals.

I'll write (or someone) IPC::SafeFork to do the above. But also draw attention to the issue.

Sphinx and daemontools

I'm moving the Big Document Warehouse Soon To Be Known As Quaero to using Sphinx for full-text searching. And of course I want to run searchd from daemontools. But searchd insists on backgrounding itself. Searching around I found people using fghack (which doesn't work) and --console (which isn't what is wanted).

However, peering into the source code to see if I could prevent it from backgrounding, I found just what I wanted: the undocumented --nodetach switch. Well, it has some documentation; there is a changelog entry that calls it a debug switch, which it isn't. Shame on you Sphinx-team!

Anyway, here is my daemontools run script:
#!/bin/bash


config=/opt/sphinx/etc/sphinx.cfg
servicename=sphinx

echo $(date "+%Y/%m/%d %H:%M:%S") $$ Sphinx searchd
exec setuidgid dw \
/opt/sphinx/bin/searchd --config $config --nodetach 2>&1 \
| /usr/bin/logger -p info -t $servicename


BTW, I have RPMs of Percona-Server (aka MySQL with a bunch of good patches) with SphinxSE.

2011/01/14

I need more RAM, Scotty!

Lookit this:
~ (root@corey:)# free
total used free shared buffers cached
Mem: 3913752 821824 3091928 0 38376 439640
-/+ buffers/cache: 343808 3569944
Swap: 0 0 0
4GB of RAM on Corey, boyee!

RAM is really cheap. I've been saying this for years. USD is also cheap these days. And I was finding Firefox really annoying at times. So I poked around Asus's site, discovered that Kingston claims that a M2N-MX SE can take 4GB of RAM. Out came the credit card. Thank you Newegg, thank you Purolator.

And yes, Firefox is subjectively much faster. Even though, as you can see above, I'm still using less then the 1 GB I had previously.

Or maybe it just stutters less. Or maybe it's the fresh reboot.

2011/01/13

Perl crumudgeon

Back last century, I read p5p-summaries, I participated in YAPC, I was active on #perl. I loved it when randal or tchrist would show us other, better, cleverer ways of doing things. I wrote some ambitious code and had some ambitious plans for all-dancing, all-singing frameworks. I one point I even looked into how to automagically build apps with Data::Flow.

Write the minimum of code and it would All Just Work.

Of course, I got over that. No framework can be all-dancing. There's a joke about a Clippy-a-like for an IDE: "I see you are writing a framework. Would you like me to a- erase this and Google for something that does what you want?"

But that's not all: I have a colocated server that runs some applications for clients. These apps were written for perl 5.004_05. I have no time nor want to get the running with a modern perl or mod_perl. But for years all the code I wrote had to with 5.004. And I insisted that POE would too.

And it now seems everyone is using Catalyst and Moose. And the shiny new things like "say" and "given/when." And perl 5.12. I JUST STARTED USING 5.8!

Of course "just" means a few years ago.

I think I've become a Perl curmudgeon, a more recent version of my associate Jean-Phillipp. When I first started working with him, he was using a modem to get to his customers, telnet and rlogin to communicate between servers, SCO and BASIC for everything. He's now accepted ssh (though I spotted an instance of rlogin last summer), gets me to install and sysadmin Linux. But still uses BASIC.

I guess I'm showing my years. "say" just looks ugly as a language construct; I have no problem typing "\n". Moose rubs me all wrong, despite it being very much aware of how much it is needed.

And while I've done a good deal of JavaScript recently, I haven't done any real AJAX, ie bidirectional. What they call comet.

In my defence, I've only really started 2 large projects in the last 6 years. These projects have taken most of my time. And with large projects, you should to stick with what the Way It Is Done or you get schizophrenic code. Not that my code isn't schizophrenic, but I've decided that just because you discovered some cool new way of doing something, you shouldn't use it the same day in an existing project. Magic is very hard to maintain.

What's more my toes are cold.

Now that I've identified the above, maybe I can change somethings and not be as hide-bound.

2010/12/22

Oh no you didn't

I made donuts.

I've been wanting to since this fall. I had some pumpkin baked, pulped and frozen, waiting for the right moment. Today, with Désirée home I thought "what a great activity to keep her occupied." Mixing up the batter together was fun, but I realised I didn't have enough oil so we headed down to the store to fetch it and she fell asleep in the stroller on the way home.

Which is just as well; hot oil and 2.5 year olds probably don't mix well.

The result: donuts which taste AWESOME! However, their texture is foul.

I blame 2 things: letting a batter containing baking powder wait on the counter for an hour. But mostly, my deep fryer. While it claims to up to 190C (~375F) during cooking I only highest I read was 135C (~275F) on my IR thermometer. So now we know why my fries take years to cook and are never crispy enough.

So, what should I do? Shell out $$$ to buy a new better deep fryer? Alton Brown claims none of them can get high enough temps. Fry in a pot on the stove and risk a spill and oil fire? While I am paranoid enough not to take my eyes off the pot, and my stoves hood and the granite counter top would probably prevent my house from burning down, I think I'll pass.

There is of course the third, geek option: modify the fryer. The problem is that the rheostat in it is sucktastic. Maybe I could add some resistance in series so that it would have a more favourable duty-cycle.

Or I could do what this guy did: short-circuit the controls in the fryer and use an external control, say a Lutron C-2000. What's more I could repurpose this for use with the heat plate, if ever end up building a smoker. The tech specs say "lights only, no appliances" but at 2000 watts, it should be more then enough to handle a fryer and would be WAY overrated for the hot plate, which is 600 watts according to my Killawatt.

Third option is of course a thermocouple, a relay and an Anduino.

Turns out a new fryer might be the cheapest option.

Now, about the title of this post. While googling I came across the KFC forum. It seems a bunch of people are obsessed about what Colonel Sander's original 11 herbs and spices were. Very few people knew. Until the Internet, a PR goof and many (I assume) test batches of chicken. And now everybody may know.

2010/12/16

Why I hate the CPAN

(OK, actually I love the CPAN, but that now that I have your attention.)

Every time I write and upload a new distro, I dream of how it's going to make some toiling programmers life wonderful, the way POE, LWP and other bits of the CPAN give my life meaning. IKC and then POE::Component::Generic where my bids at taking over the world. Or at least a certain part of it.

However uploading a distro to the CPAN is something of a commitment. My code is going to live for several years/decades, if not forever. I also do not want to be like the CPAN authors that annoy me, with inadequate test coverage, poor doco and annoying holes in their feature set.

These three points intertwine.

I'll be revising the doco and come to a point where I write "doing X is not advised/not yet implemented." Or I'll write "doing X and Y together has not been tested."

But then I kick myself with "Why isn't it implemented? Why don't I write a unit test for that edge case?" The implementation would take 20 minutes, the test cases for that new feature 30 minutes. A new paragraph of doco and now I've lost my place in my original task of revising the documentation.

What's more, I won't do it just once, but 4 times. 8 times. Before you know it, I've spent 2 days improving a module that originally took 2 hours to write.

These aren't just random numbers. The initial draft of POEx::HTTP::Server took 2 hours Monday morning, of which 30 minutes were wasted because I didn't adequately remember how POE::Session::Multiplex works. I spent the rest of the day improving on that start, then 2 more days adding features, tweaking POE::Session::Multiplex and POE::Component::Deamon because of misfeatures I'd discovered.

But backing up further, I wrote POEx::HTTP::Server because last Friday I thought to myself "Now that Sphinx integration is nearly complete, what will I work on next." And the answer was of course SPEED SPEED SPEED! So I went to look at lighttpd as a front end, with a FastCGI or SCGI call to the app server for dynamic content.

So while my real goal was to get version 2.5 of the Document Warehouse newly known as Quaero ready as soon as possible, I ended up spending a week implementing some technology from 1990. Or 1997 depending on how you look at it. And it's not over; today I realised there was a race condition in my code. A race that IKC probably shares. So a day or three tracking that down.

Still, Firebug shows 19ms response times from POEx::HTTP::Server. Of which only 5ms are waiting aka POEx::HTTP::Server generating the content the other 12 being DNS and network overhead.

Which is damn sweet.

2010/11/26

lighttpd and Thawte

Thawte have done it again: mucked about with their root cert. This did this once, years ago. You'd think they'd learn.

So, after much grief I found out how to set up a new SSL certificate in lighttpd:

domain.key is the key you signed your CSR with.
domain.cert is what you have just "Picked up" from Thawte. You want the X.509 one.
cat domain.key domain.cert >domain.pem

wget https://search.thawte.com/library/VERISIGN/ALL_OTHER/thawte%20ca/SSL123_CA_Bundle.pem
Note, please change domain to whatever the FQDN your certificate is for.

You then need to following two lines in your lighttpd config file
ssl.pemfile     = "/etc/lighttpd/domain.pem"

ssl.ca-file = "/etc/lighttpd/SSL123_CA_Bundle.pem"
The CA Bundle is a chain of certificates. Normaly, an SSL cert is signed directly by a root certificate installed with the browser. But Thawte likes doing things the hard way. So they signed a certificate with their root and now sign all new SSL certs with that intermediate certificate. So the web server has supply both the SSL cert and the intermediate certificate to the browser. That's what SSL123_CA_Bundle.pem is. If you bought one of the more expensive options, you should download another bundle.