Node.js 101: Flow Control

"I eat, sleep, and breathe PHP (or C++). How is flow control different in node.js?

The if/then/else constructs that you're used to aren't any different in node.js, but function calls are much much different. Take this code, for example:

var results = db.query(query);

This won't do what you'd expect. The results variable will very likely be null. This is because nearly every function call in node.js that involves I/O, whether it's to the network or the filesystem takes a callback function as an argument, a function which will be executed only upon completion of the request. This is due to node.js's asynchronous nature.

Taking the above example, you'd write something like this, instead:

db.query(query, function(error, results) {
   if (!error) {
console.log("Sent our query!");
Average: 3.1 (68 votes)
Your rating: None

Node.js 101: Error Handling

"Why handle errors?"

Because as a programmer, catching errors is part of your job. You need to know when a disk write fails, a database query times out, or a web service returns zero bytes. You need to be able to react to exceptional (and not-so-exceptional) conditions, and do The Right Thing, even if The Right Thing is merely to print out that error and exit.

"I can just throw an exception, right?"

In some languages, this might work. In Node.js, not so much. Remember, each time a callback is executed, it gets its own stack. Take this code, for example:

function f2() {
    setTimeout(function() {
        throw new Error("I AM ERROR.");
    }, 100);

function f1() {


Execute that, and here's the stack trace you'll get:

            if (!process.listeners('uncaughtException').length) throw e;
    at Object._onTimeout (/Users/doug/tmp/node.js/stack.js:6:9)
    at Timer.ontimeout (timers.js:94:19)
Average: 3.4 (14 votes)
Your rating: None

My thoughts on "Microsoft's Lost Decade"

Our newest feature in Windows: Space Crabs!
"Our newest feature in Windows: Space Crabs!"

There's an article making the rounds called Microsoft's Lost Decade. It's a good read. I wanted to share a few of my own thoughts on it, based on my time in the software industry.

At the center of the cultural problems was a management system called “stack ranking.” Every current and former Microsoft employee I interviewed—every one—cited stack ranking as the most destructive process inside of Microsoft, something that drove out untold numbers of employees. The system—also referred to as “the performance model,” “the bell curve,” or just “the employee review”—has, with certain variations over the years, worked like this: every unit was forced to declare a certain percentage of employees as top performers, then good performers, then average, then below average, then poor.

From my perspective, this is a really bad idea. Using Microsoft's ranking system, if you're a rockstar programmer who is working in a department with other rockstar programmers, if you find yourself lacking in skills or productivity by even the slightest bit compared to your peers--but well above that of an "average" programmer--your performance would be classified as "below average" or "poor" under the system, you would lose your job, and Microsoft would be out one rockstar programmer. (If you're been paying attention, Intel has/had this problem, too!)

Contrast this model of employee ranking with the system used at Symantec when I worked there. Each employee was evaluated in a number of areas and received a rating from 1 (poor) to 5 (excellent). To the best of my knowledge, there were no forced percentages or anything like that. Each employee was honestly evaluated based on their performance and received feedback on how to do their job better. I consider this method much saner than being rated as "poor" simply because one weren't quite as good as their peers.

Microsoft's ranking system led to some pretty horrific things:

Average: 3.4 (12 votes)
Your rating: None

Doug's Anthrocon 2012 Wrapup

Anthrocon 2012 has come and gone, and I've only recovered enough just now to actually write about it and share my pictures!

First, how about some numbers:

  • Attendance: 5,179 attendees
  • Number of fursuits in the Fursuit Parade: 1,044 fursuiters
  • Money raised for Hello Bully: $20,656
  • Number of artists in Artists' Alley: 212 artists

All of these numbers are records, way above and beyond anything we've had in previous years.  It was epic!

As usual, we had our share of of outside media coverage [1] [2] [3] That's perfectly fine however. We were in the middle of downtown Pittsburgh, after all.

Snickerdoodle and Flow Kitty

From an Operations standpoint, the con went pretty darn good this year!  Ops went well, and onsite registration went well.  Even the badge printers behaved themselves this year!  The only noteworthy issue we had to deal with was our Nexttels.  Seems that our vendor didn't bother to tell us that they wouldn't actually work in Pittsburgh.  This caused us some issues with communication, but wasn't insurmountable, just annoying.

All Cheetahs Look Alike Bierzun Wii Raver and Nyancat

Kane Husky Clementine and Boyfroend Flash Adalwolf and Shadow Destroyer

Other than that, the con was pretty much a blur for me this year.  Things went as they should have, and I mostly stayed out of the way of my hard working Ops Staff and let them do their thing.  With this growth in attendance, however, I have started making plans for staff positions and such to handle even more growth next year.

Oh, I got to see Sardyuon's Encore Performance.  The man is amazing:

Sardyuon Balancing On Chairs Sardyuon Balancing On Chairs Sardyuon Balancing On Chairs

And this is what 1,044 fursuiters look like:

Lucario The Husky Fursuit Parade Lineup Fursuit Parade Lineup

Actually, that's not entirely accurate. There is a huge group shot over here.

Say... did you know that not everybody at Anthrocon wears a fursuit? I have proof!

Anthrocon's Board of Directors and Guests

Do you want to see my full archive of pictures from Anthrocon? You can find them over over here.

Next year's Anthrocon will again be held in Pittsburgh from July 4th to 7th, 2013, and the theme will be "The Fast And The Furrious". We'll see you there!

Average: 3.4 (14 votes)
Your rating: None

Furry Connection North 2012 Con Report

I had a fine time at Furry Connection North, held in Novi, Michigan 2 weekends ago.

Fursuit Group Photo Warphammer's Photo Session Snickerdoodle

It was a "regular" working convention for me. I was on security with the Dorsai Irregulars again. I worked several shifts and then got to hang out, attend a few panels, and meet up with friends.

Intro to DJing Panel Autographed ball Creeper Sushi

Finally, here are some stats from the convention:

Total attendance: 1179 members

Fursuit Parade count: 230 fursuiters

Total Charity Donations for Mutts and Mutts Rescue: $5000 ($1,214 in cash, $440 from the poker tournament, $1,975 from the Charity Auction, and $1,371 from the con!)

DSC_5943 Quad Suit YES!

The rest of my set of pictures can be found over here on Flickr.

I had a great time at Furry Connection North, and intend to be back in 2013!

Average: 3.5 (22 votes)
Your rating: None

Introducing My Drupal Module: Fivestarstats

Screenshot Gallery (5 pictures)

I'm a huge fan of Drupal's Fivestar module. I use it on all of the sites I run. That said, I always wanted to see some reporting and stats features with the module. It would be nice to track voting activity so that I can spot instances of abuse, or see if there are any users who consistently receive low ratings. So I decided to write a separate module which did just that.

Here's what Fivestarstats does:

  • Gets total vote stats, including the average rating
  • Tells what IP addresses:
    • Are top voters
    • Are top 1-star voters (to catch abuse)
    • Have the lowest vote average. (generally mean people)
  • Tells what users:
    • Have the highest average rating
    • Have the lowest average rating
    • Have had the most 1-star votes cast against them (to catch abuse)

So where can it be found? On GitHub, naturally:

Have fun!

Average: 3.2 (16 votes)
Your rating: None

Drupal Slowdowns and the captcha_placement_map_cache Variable

So I was troubleshooting Anthrocon's website the other night, trying to figure out why pages were taking a few seconds to load, but used to be much quicker. While digging around, I saw that the filecache directory was over a Gigabyte in size. So I cleared the cache, and saw that it was still several megs in size, which struck me as odd.

Looking in the cache/ directory, I saw that the file that held the cached copy of the system variables was over 5 Megabytes in size. Definitely not normal. My next step was to check the variables table, and look what I found:

mysql> SELECT name, LENGTH(value) AS len FROM variable WHERE name LIKE 'captcha_placement%';
| name                        | len     |
| captcha_placement_map_cache | 5155086 |

It seems that for reasons I don't understand, the "captcha_placement_map_cache" variable from the CATPCHA module grows without bound. In our case, it was well over 5 Megs. This means that on every page load, a 5 Megabyte file was being read into memory and deseralized. While the filesystem cache kept the disk from getting hammered, the CPU still had to do the same work over and over.

The good news is that I could delete that variable with no ill effects, and the entire website suddenly became much more responsive. Here's a CPU graph:

drupal cpu load annotated

I'm unclear as to what's happening in the captcha module. I think my long-term solution will be to modify my DDT module to just delete that variable once it exceeds 10 K. That will keep this from ever bothering us again.

Average: 3.3 (6 votes)
Your rating: None

One of my Drupal Modules: DDT

Screenshot Gallery (5 pictures)

I'm pleased to announce my module called DDT, which stands for "Doug's Drupal Tools". (Clever, huh?)

I wrote this module to add some auditing and other functionality to the Drupal-powered sites that I run. Here's a list of its main features:

  • A command-line script for backing up an entire Drupal installation. (bin/backup.php)
  • Auditing of changed Drupal-wide variables between cron runs. (To determine if another site admin changed anything)
  • Auditing of this module being enabled/disabled (to see if admins are trying to bypass it)
  • Auditing of changes made to published/promoted/sticky/comments status on any node. (see what posts other admins are removing)
  • Auditing of changes made to comments (see if other admins are removing comments)
  • Auditing of changes made to any user's active/blocked status (see if other admins are blocking users)
  • Integration with Drupal's Flag module. This module logs whenever a node or comment is flagged or unflagged.
  • Integration with Drupal's Privatemsg module. This module logs whenever a private message is created or read.

But wait, there's more! Due to some incidents of spam and other network abuse, I added in some anti-abuse tools:

  • See what IPs a user or a list of users came from
  • See what users came from a given IP (helpful for spotting sockpuppets)
  • Search chats from the Chat Room module to investigate and verify claims of abuse, harassment, and/or spam.

So where can you get a copy? Right now, it's on GitHub:

Share and enjoy!

Average: 3.5 (18 votes)
Your rating: None

Delaware Furbowl 34 wrapup!

Just a quick post about Delaware Furbowl 34. I went the other weekend and had fun times.  Here are some of the pictures I took:



DSC_5812 DSC_5793

I wish I had a greater variety of picutres this time around, but the group picture happened earlier in the event, after which point people got out of suit.  Lesson learned for the next Furbowl I'll attend.

My full archive of pictures can be found at:

And on a personal note, I rolled a 202:

Average: 3.3 (8 votes)
Your rating: None

A UNIX Command I'd Like To See

I found this in an old LiveJournal post of mine and thought I'd share it here.

Chontamenti was a member of the abuse team at Erols Internet many years ago along with Afterburner, Neurotoxin, and others. The observant will note that each member's name was 4 syllables long. This was intentional.

CHONTAMENTI(1)            User Commands            CHONTAMENTI(1)

     chontamenti - compress spammers


     chontamenti [ -acfhLqv19 ] [ spammer ... ]

     Chontamenti compresses spammers or parts of  spammers  using
     Size-Eighteen  Boot  compaction  coding  (S16-18).  Whenever
     possible,  each spammer is replaced by one without the .nads
     extension,  while changing the ownership of  the  compressed
     body parts to group "erols".  Chontamenti will only  attempt
     to  compress spammers and other net-abusers.  In particular,
     he will ignore joe-jobs and lame forgeries.
     The amount of compression obtained  depends on  the original
     size of the spammer's genitalia, head, and colon. Typically,
     an average chickenboner can be compressed by 20-30%,  with a
Average: 3.8 (10 votes)
Your rating: None