A couple of notes to keep in mind:

  1. If you’re meeting passengers coming in on an international flight, and you’re thinking that the waiting/meeting area outside customs on concourse J is a sensible place to meet your inbound international party when the info screen says they’ll be arriving at concourse J, you’re half right (it is a sensible place) and half wrong (there’s a pretty good chance your party will arrive two floors below and you’ll miss them, if they’re coming from Canada).

  2. If you want to catch a shuttle to the hotel where your party is staying, after realizing that they’re long gone, and you’re thinking one of the dozen or so shelters marked “Hotel Shuttle” would be a sensible place to wait for one, you’re half right (it is a sensible place) and completely wrong (not a single airport shuttle actually stops at any of them). The proper approach is to go to the departures area, watch for the shuttle from the appropriate hotel, and then stand in front of it so it either has to hit you or let you on (the former would take more time to deal with, so they tend to stop).

This public service announcement has been brought to you by someone who spent way too much time not meeting his party at the airport today.

Oh, and one more thing that’s actually somewhat useful — if you want to get from Fort Lauderdale to Miami airport, and if you ask a hotel concierge, they’ll recommend a private sedan for $90 one-way. Go Shuttle quotes $120 one-way. If you persevere, you might get a taxi for $60 one-way. Don’t do any of these. Instead, take the commuter rail for $3.75 airport-to-airport, or $6.25 for a same-day round-trip ticket.

Product Warning Labels

I read the following warning label on a speaker a few days ago:

Take note that this speaker is not edible and should not be placed in your mouth.

It’s admittedly a small speaker, but still!

I wish that, just once, some terrorist would try something that you can only foil by upgrading the passengers to first class and giving them free drinks. — Bruce Schneier

That would certainly beat the various draconian and invasive measures I’ve been reading about. And it’s not as though any of them would even work. Most of them wouldn’t even have prevented the latest attack that got prevented just fine without any of the new proposals.

Security is hard. In this case, you’ve got quite a lot of airport security people who aren’t getting paid exceptionally well trying to catch one person out of every billion or so travelers who’s willing and at least mostly able to blow himself up. And you need to do that on tight schedules with no false positives.

To make things just that much harder, everyone else in line is already annoyed with you because of the existing inconveniences of travel and airport security, often combined with long lines, making it exceptionally easy to get a false positive based on behavior (if anything, you probably need to be most concerned about anyone who looks serene through the whole process). And that’s just a couple of the issues involved.

Sigh. I’m going to be flying in less than a week, going to a mostly undisclosed location for a business-planning retreat. Hopefully some of the hysteria will have died down by then and I’ll be able to legally at least read a book during the flight. If I hadn’t already prepaid the entire trip, I’d cancel it and go find a cottage in Maine instead.

A refreshing signature

I just saw the following signature, from someone who’s not caught up in the whole paperless-will-save-the-world craze:

Notice: It is totally OK to print this email. Paper is a biodegradable, renewable, sustainable product made from trees. Growing and harvesting trees provides jobs for millions of men and women, and working forests are good for the environment, providing clean air, clean water, wildlife habitat and carbon storage. When you don’t need it anymore, be sure to put it in a bin designated for recycling, and it will come back to us as new paper or paperboard!

Rule #1 of Caching

Don’t cache something if it takes longer to retrieve it from the cache than it takes to generate it in the first place.

Corollary: Improving performance on the cache mechanism allows more stuff to be cached effectively.

This was discovered while attempting to speed up the work list and order detail pages. Fortunately, adding an index in a particular place in the database was enough to get the cache retrieval and validation to be well under a millisecond.

That, combined with roughly eight hours of tweaking code and database calls, means that an average order detail page request now only requires 182 database calls, down from 689 (74% reduction), and is generated (in most cases) in well under a second, even without touching the cache.

With the cache, it’s generated in roughly a tenth of a second (with about ten database calls for the entire request), though I still have some work to do, since it’s taking the browser between a quarter and half a second to render.

The work list load time is just under a second now, with some selective caching, down from about 2-3 seconds, using a test set of 40 active mailings. That’s fast enough for now. Database calls also dropped from 789 to 402, which is a nice bonus. At 100 active mailings, it slows down to about 1.5 seconds with the selective caching (down from about 10 beforehand), so I’ll probably need to do some more performance work once we start seeing that on a regular basis.

When "right now" isn't fast enough

Normally, my company is able to do a good job of meeting or exceeding people’s expectations for order fulfillment. We certainly try. Even during this crazy time of year, when there’s a ton of mailings, nearly all of them unusual, often under-specified, and with lots of people stressed out over sending the order a week or three later than they’d hoped, we’re keeping up (if barely, and with somewhat less sleep than usual on the part of myself and Christine, but as well as or better than past years).

Yesterday, though, an order took a turn for the strange. This particular order had been submitted the day before at 3:28pm. That’s after our mostly-unofficial cut-off for the day (3:00pm), and there were no special instructions about it being a rush, so we went through our normal practice of waiting ‘til the next morning to work on it.

Mid-morning the next day, we get an E-Mail from the customer asking how backlogged we are, how long it will take to get his letters sent, and whether it would be faster for him to send them himself. An hour later, having just talked through the (moderately complex) order with Kevin, I reply saying that we’re not backlogged, and are working on setting up his mailing now. Assuming there’s no delay in approving the order, we’d have the letters sent that day.

Nothing weird so far, but then the next E-Mail arrives. “I think I’ll send this mailing myself” (to get it out sooner). Err, what? So, I send back a reply, asking if he’s sure, and repeating that we shouldn’t have any trouble getting the mailing sent within a few hours. Maybe he’d misread the original E-Mail. But another reply comes in, saying he’s sure, so I cancel the order.

I’m guessing there must have been some other issue. It was admittedly a small list, so it’s technically possible that if he dropped everything and started work on them right away, he could have gotten the mailing sent before we would, assuming he could produce 4x6 photos at a nearby 1-hour lab with no delays during the busiest time of year, and assuming he already had a pile of the specialty reply envelopes he’d requested, along with the normal paper, envelopes, and stamps. It only would have taken us roughly 10 minutes to send his mailing, including the photo printing, but he wasn’t at the head of the queue at the time, so it would’ve been an hour or two before it got to the printing stage.

Even so, it wouldn’t have mattered — at least in this area, it makes no difference if I mail something at 7am or 8pm; it’ll still go out that day in the ~11:30pm truck. I assume the same is true where he lives (if anything, he’d probably have a 5pm cutoff), and his recipients were spread out around the country, such that there wouldn’t be any major savings geographically.

That one may very well take the cake for oddest customer interaction of the year.

Deef in Texas

Before this evening, the closest I’ve ever been to Texas has been either northern Colorado or Florida, depending on how you want to measure geographical/cultural distance. Next thing you know, I’ll be visiting California — scary thought!

Travel was pretty boring, all told. I got caught up on E-Mail (offline) during one of the flights, and played Bejeweled on the other, with a stop at Chick-Fil-A in Atlanta (albeit a rushed one, since I’d arrived in Concourse C, had a flight leaving out of Concourse B, and it was in Concourse A).

Wednesday afternoon in Manchester is apparently a great time to fly. The airport is dead quiet. No lines for check-in, security, or food. Way better than flying out of Boston.

Oh, and I should probably mention why Deef is in Texas. I joined the National Association for Printing Leadership (NAPL) a little over a month ago, hoping to improve my understanding of the industry and also to improve my company’s foundation by figuring out and implementing some best practices for the printing side of things, much of which looks like it’ll carry over into the technology side as well.

These guys have a conference every year for owners of smallish print shops, which happens to be in Austin, TX this time. So, here I am. It should be fun!

Unreleased Product has #1 Position in Google

Just for curiosity’s sake, I did a search yesterday for the name of a product that I haven’t released yet, and which I’m pretty sure I haven’t mentioned anywhere (by name, at least) on the web.

Imagine my surprise when I found it already has the #1 position in Google for its name!

Freaky. But it does explain why some people have already found said unreleased software program that was in theory only accessible by knowing the right domain name to type. The domain name is descriptive enough that a search on other terms would let you find it.

Six of one, half a dozen of the other

I just read the following in a brochure:

(Such and such) is optimized for label printing with the ability to print 2” per second in black and 10’ per minute with full color.

Unit conversion in comparisons can be used to make a stat seem better than it really is (or worse, if that’s your goal). Color printing is usually slower than B&W printing (on account of there being a lot more data/work involved), and I’m curious how much slower it is, but in this case, I think someone just messed up:

  • 10’ = 120”
  • 1 minute = 60 seconds
  • 120” per 60 seconds = 2” per second

I wonder if it was supposed to be 10” per minute instead of 10’…

Neat SQL Query

Update a table according to the results of another query (slightly simplified):

UPDATE letters AS final
   SET preview_file_id = outer.preview_file_id
  FROM (SELECT letter_id,
               (SELECT preview_file_id
                  FROM inserts AS i
                 WHERE i.insert_id = inner.insert_id) AS preview_file_id
          FROM (SELECT letter_id,
                       MIN(insert_id) AS insert_id
                  FROM letters AS l
                  JOIN letter_insert_ref USING (letter_id)
                  JOIN inserts AS inner_i USING (insert_id)
                 WHERE l.preview_file_id IS NULL
                   AND inner_i.preview_file_id IS NOT NULL
                   AND l.submitted > NOW() - '1 month'::INTERVAL
              GROUP BY letter_id) AS inner) AS outer
 WHERE final.letter_id = outer.letter_id;

Or, in something resembling English, “In the letters table, set the preview file according to the following list of recent letters and the associated preview files for the first insert of each of those letters.”

There might be a way to simplify the two sub-queries into just one using grouping, ordering, and limiting, but this worked well enough for a one-off query.

Background: I thought I no longer needed the previewfileid field in letters, so I deprecated it recently, and stopped setting it. The API layer had a workaround, but there’s still a program that uses a database view that needs the previewfileid to be set in letters, so I needed to revert that change and back-fill the previewfileids that didn’t get set. UPDATE FROM to the rescue!

(Also, if anyone has any layout suggestions on how to make complex SQL more readable, I’m all ears. I’ve been center-aligning to the keyword for years just because I haven’t found anything better.)

Elsewhere on the Web

My Amazon.com Wish List