Customer service starts with the customer

May 9th, 2008

On Thursday I received a very strange phone call on my work line. Caller ID indicated only that the call had been transfered to my desk from elsewhere within the company. In the past, this has almost always been the calling card of recruiters. They find my profile on LinkedIn but don’t have my phone number. They know I work at Yahoo!, however, so they call the receptionist and ask to be transfered to me.

This time was different, however. I answered the phone, “This is Ryan.” Booming from the other end of the line I heard, “RYAN” in a strong southern accent. What followed could only be described as 5 minutes of nonstop railing against Yahoo! Customer Care. This gentleman had lost the password to his Yahoo! Mail account and over the course of the last week felt he was being given the runaround by our support technicians, going as far as to say that they had been “rude and hateful” towards him.

Working on his last nerve, he somehow found out about Yahoo!’s “postmaster Ryan K”. I’m nearly certain he’s referring to Ryan Knight, the “Ryan K” who took over the Yahoo! Mail blog after I hung up my evangelism cape. He managed to find the number for the Yahoo! Sunnyvale office and asked the receptionist to connect him to “Ryan K”. There’s more than one, so I can only guess that the receptionist rolled the dice and transferred him to me. Fortunately, he found a sympathetic ear.

After listening to him throw the customer care group under the bus for 5 straight minutes, we finally got to the part of the phone call where he would let me participate in the conversation. I asked some questions to collect as much information as possible. I tried to explain some of what might have happened during his dealings with customer care. He explained how important his email account was and how frustrating dealing with our customer care group was. He wasn’t happy and he wanted to make sure I was keenly aware of that fact.

After about 10 minutes on the phone with him, however, something happened. He came to know that I understood his frustrations and that I was equally disappointed with the experience he had been going through. In that instant, the phone conversation immediately lightened up. We each cracked a few jokes, shared a couple of laughs, established some common ground. Over the course of the next 5 minutes I collected a little more information and told him that I’d work my backchannels to get him the help he needed. It was the full 180. He started the phone call with spite and venom and he finished the call hopeful that we’d have this situation resolved for him. He was appreciative and, dare I say it, a bit happier.

Whether you’re dealing with 250 users or 250 million users, you can’t service your customers without talking to them. I mean really talking to them, not handling them with a phone in one hand and a script in the other. Talk to them, get to know them, understand why they’re upset and then make it all better.

Activator: Pimp my buddy list

May 1st, 2008

Neal’s Web 2.0 video is up on YDN now. This is his YOS talk and includes a sneak peek of my new project, Activator, at about 30:20 into the video.

True to it’s name, Activator is here to activate your social graph. It’s meant to help out with “cold starting” social networks. Many times when you first arrive at a social network, you have no friends and no clear means of how to find your existing friends. Activator’s charter is to find those people for you and surface them so you can quickly and easily add them. I’m still trying to figure out what’s the best way to write openly about Activator without getting myself into trouble. For now, check out Neal’s video and you’ll see a quick screenshot of what Activator may look like when released.

My new Yahoo! project

April 24th, 2008

Well, I guess now that Ari and Neal have totally totally let the cat out of the bag about YOS, I finally get to talk a little more openly about my new project: Activator. There’s a short paragraph in that article that mentions Activator:

The activator engine handles the combining of different relationship groupings, such as the Yahoo Mail e-mail address book, Yahoo Messenger contacts, Flickr friends, Yahoo 360, and Yahoo Mash, Sample said. Yahoo will be careful to protect user privacy and won’t apply the information without user consent, he added.

That’s not a great description of Activator, kind of leaves you wondering what the hell it actually does. As soon as I figure out how much I can talk about it I’ll post more. In any case, when you hear them talk about Activator you can think of me.

Code coverage != code quality

April 20th, 2008

My current project has a new requirement that in order to be feature complete we must reach 80% code coverage with our unit tests. At first, this seems like a good idea. You want to ensure code quality. Unit tests can help with that. So you figure you’ll come up with a way of measuring how much of your code is being tested. Soon, however, deadlines get tighter and actual features need to be finished. The code coverage is short of the required 80%. So you take the following code:

   if(unreachable) {
      doTheUnreachable();
   }

   int codeCoverageRequired = 80;
   cout < < "Feature complete requires " << codeCoverageRequired << "% code coverage" << endl;

This code has 4 executable lines of code, only 3 of which are being executed. You’re only at 75% code coverage. So you make the following change:

   if(unreachable) {
      doTheUnreachable();
   }

   int codeCoverageRequired = 80;
   cout < < "Feature complete requires ";
   cout << codeCoverageRequired;
   cout << " % code coverage";
   cout << endl;

This code has 7 lines of executable code, 6 of which are being executed. Now you’re at 86% code coverage. You’ve boosted your code coverage numbers by 10% simply by adjusting some lines of code. The quality is no better, but your code coverage is higher.

You can also play games by under-reporting the total lines of code in your project. As it turns out, this is easier than you might think. The code coverage tool we’re using (gcov) appears to have an issue with not reporting the lines of code in files that don’t get tested at all.

By gaming the system you’re able to give management the warm, fuzzy feeling that the code quality is high when, in truth, the opposite may true. Even a high code coverage number without gaming the system doesn’t necessarily mean that the code quality is high. Take the following, for example:

   size_t function( void *ptr, size_t size, size_t nmemb, void *stream) {
      ((string*)stream).append(ptr, size * nmemb);
      return size * nmemb;
   }

   string requestUrl(string url) {
      static string buffer;

      CURL* ch = curl_easy_init();
      curl_easy_setopt(ch, CURLOPT_URL, "http://unclehulka.com/ryan/blog/");
      curl_easy_setopt(ch, CURLOPT_WRITEDATA, &buffer);
      curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, writehandle);
      curl_easy_perform(ch);
      curl_easy_cleanup(ch);

      return buffer;
   }

If you call requestUrl() from your unit test, you’ll end up with 100% code coverage, however this code is as buggy as it gets (see the ’static string’ declaration).

The lesson is if you want to ensure code quality, use something that actually measures code quality.

Krav Maga - Day 7

March 27th, 2008

Yeah, okay…totally lagging in posting this. Day 7 was this past Saturday (3/23). We started out slow with our warmups. Running around, touching shoulders, dropping and doing pushups and situps. We eventually partnered up. I joined up with a well-tattooed guy about my height but, perhaps, a little bigger than me. We did a bunch of 1-2 punching combinations with the heavy pads. The best part about my partner is that he barked. Not literally, but the noise he made as he exhaled with every punch sounded just like a dog. At one point, Lisa looked around wondering who let the dog in the gym. Then she realized the dog was beating the living hell out of my blocking pad.

We eventually got back to knees. This time I partnered up with another Ryan. The name was the only thing we had in common, he was a head taller than me and much, much stronger. When we did knees he was either throwing me 3 feet backwards or 1 foot in the air. That being said, it was more enjoyable than the last guy who did a number on my jaw. We focused a lot on the knees that involve a hold. In the first, you grab your partner by the tricep and shoulder and then ram your knee into them. In the second, you lock your hands behind their neck, pull them in towards you and throw your knee into their face/chin/chest.

The conditioning is getting a little better. I’ve been doing some conditioning on the side. Using a deck of cards, I turn cards face up one-by-one. Every red card is pushups, every black card is squats. Aces and number cards are 1-9, face cards are 10 and jokers are wild…20 pushups or squats. This past Monday I got through 30 cards in 30 minutes, finishing 95 pushups and 120 squats. Doesn’t sound like a lot for 30 minutes, but it’ll get your attention. I can’t take credit for this hellish workout. Credit for that goes to Matt Furey’s book, Combat Conditioning.

Speaking of books, our school carries Complete Krav Maga, which features pictures of one of my instructors (Kirian). I’m going to pick up a copy soonish.

Krav Maga - Day 6

March 19th, 2008

I skipped Krav Maga on Saturday last week (trying to give my thumbs more time to heal up) so this past Monday was day 6. I’m a little behind in posting this, so hopefully I remember everything.

As usual, Jesse worked us over pretty good from the start. I have to say, my conditioning is improving. I still get tired and it’s still difficult to keep my hands up through long drills. But it’s getting easier. I’m no longer doubled over gasping for air during drills. That’s really the strongest measure of what three weeks of classes has done for me. Technique is great and all, but I need to get back in shape.

We did a lot of punching and kicking combinations as a warm up. Eventually, Jesse turned us loose doing hammer punches. Imagine you’re hanging a picture on the wall and you’re putting up the nail. Clench your fist like you’re holding a hammer and hammer the nail into the wall. Now take the hammer out of your hand and replace the wall with your partner, holding the heavy bag. Generate power from the legs and twist the trunk, transferring power to the shoulders and drive the bottom of your fist into the bag as hard as possible. When done right, your partner will wonder if you’re about to stop their heart with these blows (I was getting concerned when my partner was wailing on me). We started out with just the right and progressed to left-right combinations. Periodically Jesse would signal for us to go “all out”, hammering with the left and the right in rapid succession, as hard and as fast as we could. It’s a pretty devastating blow. Imagine leading with a kick or knee to the groin to double your opponent over and then driving a hammer fist into the back of their neck. Yeah, brutal.

We also did some work on getting out of side headlocks. Imagine someone comes up to you from the side and wraps their arm around your head and neck from the side. They pull you to one side, knocking you off balance and torquing your neck in the process. The counter is to go with it. If the attacker comes from your left and pulls you that direction, pivot on the ball of your left foot, swinging the right foot in the direction the attacker is pulling you. When your right foot lands, you should be perpendicular to your opponent and as close to them as possible. The free right hand swings downwards and then up, into their groin. Strike at least once, preferably two or three times. As this is happening, the left hand goes up, eventually coming between your head and your opponent’s head. With the left hand, you smash the bridge of the nose with your palm and grab the chin with your fingers. Pull back, causing the head to tilt backwards. At this point, your opponent is wide open for a range of different attacks. Punch the face or throat. Better yet, bust out that powerful hammer punch you just learned.

It’s great fun. I was paired up with Nate, a level 2 student that I’ve worked with before. He’s big and not afraid to smack me around a bit (other people seem to think you’re made of glass at times) and he’s really good at telling me everything I’m doing wrong. After a few minutes I was getting the hang of it, but then class was over (pitty).

My thumbs are still pretty torn up, but are getting better. I managed to get out of this class without any new injuries, although one of my partners managed to poke me in the eye pretty well during one of the drills. No biggie, I made sure to put a little extra mustard on the hammer punches to return the favor. ;)

In other Krav Maga news, we were given handbooks by the school. Among other things, it details what we’ll learn at each level. Let’s just say that the first item on the list for the green belt curriculum (level 3) is head-butting. Just 10 months to go.

Krav Maga - Day 5

March 10th, 2008

Before you ask…yes, I plan to blog every day of Krav Maga.

After the class on Saturday, I was looking forward to a slightly more tame Monday class. Jesse, the Monday instructor (and Saturday assistant), usually spends more of his class going over technique. That means things slow down a bit giving you more time to catch your breath. Today however…he had some surprises for us.

Things started out pretty normal. Some running (with ~16 people in a crowded room, running becomes interesting) along with pushups and mountain climbers to get the blood moving. After that we partnered up. I was teamed up with the 14 year old in the room, not his lucky day. If he was lucky he weighted around 130 pounds…roughly 100 pounds less than me. We started out with one person on all fours. They then piked up so they were on their hands and toes with their butt up in the air. The other partner then military crawled underneath them to the other side. One there, the partner on the ground dropped low, allowing the other partner to jump over them back to the starting position. The person on the ground goes back into the piked position and we start over. At one point, the instructor blew his whistle and we went either all under (back and forth) or all over (back and forth). It was insane, I’ve got the carpet burns on my knees to prove it.

When that was over, one partner again got on all fours. The other partner then sits on their shoulders, hooking their feet around the other partner’s knees on the ground. The partner on top leans back and sits back up…kind of like doing a situp. This is where the weight discrepancy came into play. I started on top, leaned back and the kid’s arms buckled and I flattened him like a pancake. Fortunately I caught myself with my arms and managed not to pop his skull. Not wanting a lawsuit, they found me a larger partner.

When that was done we went back to punching and kicking drills, this time moving around the classroom to get used to throwing punches while on the move. Usually we stand in one place and throw them, so this was a nice change of pace. These punching and kicking drills still kill me. My arms get tired and it becomes difficult to keep the hands up, which is essential in any combative confrontation (protect your head at all costs).

We wrapped up with more choking. I pitty the fool who tries to choke me from the front. He’s in for a rude surprise, roshambo style.

I feel like my conditioning is improving. I won’t say it’s good, because it’s not. I’m still the fat guy huffing and puffing (sometimes wheezing) with his hands on his knees. But I’m huffing and puffing a little less and I’m going on three weeks without missing a day. I dare say I’ve even dropped a little bit of fat over the past week, according to the scale anyway.

Important safety tips when handling json-c

March 10th, 2008

We’ve been using json-c internally for parsing and generating JSON in my new project. It’s a pretty nasty interface to work with, so I’ve been considering putting a prettier face on it for C++ developers. Today I sat down to do that. Instead, I spent many hours allowing json-c to repeatedly win games of roshambo.

It started out simply enough, a simple class to wrap the json_object:

#include <string>
#include <json/json_object.h>

class JsonObject {
    private:
        json_object* obj;
        JsonObject();

    public:
        static JsonObject parse(const std::string& json);
        ~JsonObject();
};

There wasn’t much to it at this point, but I had enough to set up my Makefile to check that everything compiled properly. Sadly…it did not. While the compilation step was successful, linking wasn’t so fortunate:

libjsonwrapper.so.1: undefined reference to `json_object_put(json_object*)’
libjsonwrapper.so.1: undefined reference to `json_tokener_parse(char*)’

I spent some time (and by some time I mean most of Sunday) futzing with the Makefile, making sure json-c was properly installed, compiling my own version of json-c, checking different hardware architectures and operating systems…all with no luck whatsoever. I even looked at some other code that we have that uses json-c, checking out the Makefile to see what that code was doing that I wasn’t.

At around 8:45pm I took a break and went for Sunday bowling (Homestead Lanes does a special on Sunday nights, it’s great…you should go sometime). When I got home, I dug back in. Still no dice.

So I went back to the other code we’d written that uses json-c and looked at some other things. Finally, I happened upon it:

#include <json/json.h>

It’s subtle, but including json.h instead of json_object.h makes all the difference in the world. At first I didn’t want to know why, I was just mad that it mattered at all. Obviously json.h is some aggregate header that keeps you from having to #include every little file you need. But clearly it’s also performing a little black magic along the way that does something to affect linking. Ready to lose my shit, I dug into the header:

#ifdef __cplusplus
extern "C" {
#endif

#include "bits.h"
#include "debug.h"
#include "linkhash.h"
#include "arraylist.h"
#include "json_util.h"
#include "json_object.h"
#include "json_tokener.h"

#ifdef __cplusplus
}
#endif

Whoomp there it is: extern “C”. If you include json.h it does the right thing and makes everything inside of json-c use C linkage when compiling C++. If you don’t include json.h and instead include one of the files that it includes…then nothing uses C linkage causing the linker to FAIL.

Thanks json-c for consuming a day of my life that I can never have back.

Krav Maga - Day 4

March 8th, 2008

So, today was…different. Like last Saturday the instructor really stuck it to us. We ran in a big circle for a while, switching directions on demand. Seemed almost tame. And then his inner masochist woke up. Five jumping jacks, five squats, five burpees, five pushups, five mountain climbers…repeat. We did that for what seemed like five minutes.

We finished up with that and then paired up. I found someone roughly my size, although he was definitely a few levels above me. We did the usual: punch and kick each other. Then they decided to teach something else…knees. It started out simple, knee the other person at 50%. Then the instructor gave the word: grab your partner around the neck and go to f’ing town on the pad. It seemed okay at first, the guy was pummeling the pad (and the back of my neck) but I was okay. Then he started landing blows high on the pad, sometimes slipping just past the pad to land a shot on my chin. Just to mix things up, sometimes he’d go low on the pad and nail me in the stomach…not far from the jejunum I’d guess. It was awful, pad or not.

We wrapped up doing an A-B drill. Three person teams. One on each end of the gym and one person in the center. The person in the center listens for the instructor to yell “A” and “B”. For “A” they run to one side and punch the hell out of the bag. For “B” they run to the other side and kick the hell out of the bag. The instructor periodically throws in some twists, switching right in the middle of running from one to the other. At one point, the instructor switches the “A” pad holders to knees. While the person is kneeing the hell out of the pad the “B” pad holders run up behind the person in the middle without them knowing. Now when the instructor calls “B” the person turns around and immediately starts punching the pad. It was pretty greulling.

Now, at the end of the day, all I feel is my jaw. I think all of the knees that missed the pad and clipped my chin did a bit of damage. Nothing permanent, I hope.

Krav Maga - Day 3

March 3rd, 2008

Today started my second week in Krav Maga classes. I’m starting to feel like I can keep up better physically with the class now. I’m not saying I don’t double over, gasping for air in the middle of a drill…but I do it less often now. Of course, the class today was less heavy on the insane, nonstop drills. We stopped more often for the instructor to demonstrate a technique.

We started out doing running drills. The heavy bags were brought out (more about those later) and we had to slalom them (in and out) down one end, sprint back and slalom the next row of bags. On the instructor’s signal, we were to stop, find a classmate and do our “touch the shoulders” drill (try as hard as you can to touch your opponent’s shoulders while preventing them from touching yours). When he signaled again, back to running. At one point, he turned out the lights and even strobed them to simulate adverse conditions. He likened it to being in a brawl in the middle of a carnival. People and obstacles everywhere with limited visibility.

We spent a bit of time on punches, working on the fundamental 1-2, left jab, right jab punches. We worked with the tall, heavy bags for the first time today (they have this awesome track that the bags hang from, allowing you to move the bags around the room). We did some simple 1-2 combos, eventually going to power punches (hard as you can) and finally all-out (hard as you can, fast as you can). This is exhausting stuff…when you’re done it’s hard to keep your hands up. In between rounds of that, we were also doing pushups.

We also did a drill in teams of three. One person held the large punching bag, one person did everything they could to demolish the bag with their fists, while the third person did everything they could to keep the puncher away from the bag. This was insanely exhausting. I ended up with two guys that were both larger and more fit than I was. By the end of the rotation (everyone going through each assignment once) I was dead. It was great.

We also spent some time on close in combat with the elbows. This is the first time I’ve done elbows in the class. We started with what the instructor called #1, which involved striking across the body with your right elbow at about chest/chin height. Then we moved to #2, which strikes away from your body with your right elbow (standing straight, look right and throw your elbow in that direction). We then moved to #7 (I guess #3 through #6 will come later), which is the elbow straight down (imagine your opponent doubled over in front of you and deliver a blow to the back of the neck/spine with your elbow).

Once we were comfortable with those, we went back to choking drills. This time, instead of breaking the grasp and kicking the balls (like we did both days last week), we fall back two steps, establish our fighting stance, raise our right arm straight up and do the #7 elbow, breaking the choke. From that position, we went immediately to the #2 elbow, aiming for the face of the person choking us. I got to practice on Lisa, which was fun. Whenever we do the choking drills, she always ends up with red marks on her neck from my thumbs. I imagine being pulled over by the cops on my way home with red marks on her neck and my knuckles bloodied up. That should make for interesting conversation.

Another week or two of this and I think I’ll be ready to up it to 3 days a week. But we’ll see how I feel tomorrow and Wednesday. In any case, Krav Maga is awesome. If any of this sounds at all interesting to you, I highly recommend it. Great workout, practical self defense, cool instructors and all-around good time.

Krav Maga - Week 1, Day 2

March 3rd, 2008

Saturday was our second Krav Maga class. Unlike Monday, which was a Level 1 class, Saturday is an “all” class. I think it means all levels are welcome and they’ll pick some lowest common denominator routines to go through. The class was a bit larger than the Monday class. You could really tell when we were all lined up doing pad exercises, there just wasn’t room to move. Hopefully that’s not what it’s always like. I’m not crazy about really crowded gyms.

We did a lot of the same exercises as the Monday class. This time instead of being pummeled by a much larger classmate, I was matched up with an older but similarly sized gentleman. Of course, he’s been taking the class for the last nine months. I figured he would be easier on me with his punches than my Monday classmate…wrong. He seemed to take great joy in pounding my chest with his fists. I found it amusing that he was happily pounding the piss out of me while wearing his “I’m a vegetarian” shirt.

I think I fared better than I did on Monday, although I still get winded and need a short break to catch my breath. I was sore across the top of my back and shoulders Sunday morning when I woke up. Other than that, no issues, however. That’s a good sign since I have a quick turnaround to get to the next class on Monday. All in all, I’m really enjoying it. The workout really kicks your ass and you’re learning practical self defense.

Krav Maga - Week 1, Day 1

February 25th, 2008

Inspired by a recent episode of Fight Quest, Lisa and I went to check out a local Krav Maga school on Saturday. We sat through 30+ minutes (out of 3 hours) of a belt test for about 14 students. While not nearly as intense as the Fight Quest footage was, it was still pretty brutal watching them go through their warmup routines.

Tonight Lisa and I had our first class at the Academy of Self Defense in Santa Clara. They gave us two free weeks to check it out, so we dropped in on the 7pm Level 1 class. Let’s just say that Level 1 is only referring to the competency level, not the intensity level. The class started out with us mounting punching bags on the ground, pounding our fists and elbows into the imaginary face of our enemy. When the instructor blew his whistle, we rolled on our side to our backs, grabbed the punching bag handle and proceeded to wail on the virtual assailant’s face with our fists. That went on for about 5 minutes.

After that, we paired up for more work. I paired up with someone slightly taller but considerably larger than myself. Mistake. We took turns punching the bag that the other was holding up. I landed some strong rights, but my left is weak by comparison. We switched and my partner took turns pummeling the bag with his ham sized fists, driving the air out of my lungs with every punch. Seriously, I’m pretty sure the pad is just there to make sure I don’t get a bruise or a broken sternum because it wasn’t doing much to prevent his powerful blows from pushing me backwards.

After a few minutes of that, we started running around like mad. Literally. One of us ran with the pad while the other ran with nothing, sprinting through the crowded classroom, dodging the other students. When the whistle sounded, the person with the pad stops and the other person seeks them out to take out some sweet aggression on the pad. Once again, wind being knocked out of my lungs. On a related note, don’t let the pad come away from your chest…or else it just gets repeatedly driven back into your chest by your partner. Also, don’t let the pad dip…or else it will be driving dinner out of your stomach instead of air out of your lungs. Words of wisdom by Ryan Kennedy.

There were some other drills. Voluntary amnesia is suppressing those memories in the hope that forgetting the misery means I’ll go back for more. We did some choking. One partner chokes the other. The person being choked has to simultaneously break the choke and kick the other person in the balls. The choking might explain the amnesia.

That brings up a fun topic…rules. There are none. In other martial arts there are things you don’t do. You don’t gouge the eyes. You don’t strike the back of the neck. You don’t kick the balls. All of those are the bread and butter of Krav Maga. Crushing the testes of your opponent is how you start the fight. Most martial arts start with a bow. Krav Maga subscribes to the roshambo school of starting fights. This lack of rules is really what draws me to Krav Maga. There are no formalities before the duel. There is no referee. There are no points. You win if you don’t die. It’s reality based fighting, this is how it’s going to be if you’re attacked on the streets or on a battlefield. Bow to your opponent? Not unless you want him to kick you squarely in the face.

We rounded out the night with 10 jumping jacks and 10 burpees. Well, the class did. I was able to do about 5 jumping jacks and prevented myself from performing any vomitees. It was brutal. My hands are chewed up from the punching (my poor, delicate, programmer hands) and the physical exertion is flat out exhausting. I loved it, I’m going back on Saturday and I’m going to do it all over again. With luck, I’ll loose some weight and get back in shape while learning some practical defense techniques.

Wanna join me? It’ll be great.

Smoking in a pot

February 3rd, 2008

Inspired by the likes of Alton Brown and my friend Jed, I took on the terracotta pot smoker this weekend. Why? So I could make pulled pork for my Super Bowl party.

Aside from getting totally smoked out by it and having to jigger with the lid to get my 7.25lbs Boston butt in there, it’s gone well. The only real hitch has been the thermometer. The first thermometer I used, a replacement smoker thermometer was registering temperatures below 200F. I was about to give up when I figured I’d try another thermometer and it read much higher numbers (around 219F). I’ve switched to that one and the 2-3 hour smoke is underway.

It’s like cooking with MacGyver…it’s awesome.

I think we’re gonna need a bigger boat

January 29th, 2008

Have you ever watched one of those nature shows about sharks (yes, Jaws counts) where they throw chum overboard to attract the sharks before they throw in the divers? Lately it seems like Yahoo! is the boat, the media is doing the chum’ing and other Bay Area companies are the sharks (we already know who plays the role of the divers).

I’ve been getting a lot more recruiting requests lately, including one that explicitly called out “changes at Yahoo!” as a reason for getting in touch with me. Don’t get me wrong, I appreciate the attention and all. It’s good to know that if I were to accidentally fall off the Yahoo! boat that plenty of sharks would be in the water, ready to…eat me.

On the other hand, it would be nice if the sharks didn’t jump in the boat trying to eat me before Yahoo! casts me over.

2007…another mixed bag

December 27th, 2007

2006 had a pretty rough ending for me. I moved from Folsom back to the Bay Area only to have my cats get into a huge fight (a result of move stress and misdirected aggression). It took months to get them back together so we could return to a semi-normal life. I took over as Yahoo! Mail Beta evangelist. That sounds like a good thing, but it wasn’t. It was fun, don’t get me wrong. But the added responsibility and personal investment simply weren’t worth it. I managed to come down with shingles, merely the first in a long string of ailments to come over the next several months.

So when 2006 was coming to an end 12 months ago, I was happy. I was ecstatic. A clean slate. So, did everything go as planned? Yes…and no. Mostly no.

January 2007

January picked up where December left off, with me in questionable health. I caught a cold and discovered (the hard way) that I have sinusitis. As it turns out, sinusitis can cause you to faint. I woke up one morning, walked into the kitchen, began preparing breakfast, became light-headed and passed out right there in the kitchen. Fortunately, Lisa was there and quickly pulled over a chair before I went down. I sat in the chair and went lights out. Good fun…wait, no…it wasn’t.

March 2007

I enjoy traveling for work. Yahoo! picks up the tab and I get to go different places. In March, Yahoo! sent me to San Diego for the O’Reilly Emerging Technology conference. I wasn’t there to sit in sessions, however. I was there for the official launch of the Yahoo! Mail Web Service. The culmination of my 2+ years at Yahoo!, releasing the web service to the public was a great personal and professional moment. Years of hard work and patience finally paying off.

April 2007

Every high must be countered by a low. It’s a law of physics…or something. A short month after releasing the Yahoo! Mail Web Service, I was sitting in a meeting. The agenda was a feature. A feature that exists in Yahoo! Mail Classic but doesn’t exist in the new Yahoo! Mail. I was there with several other people, trying to convince the powers that be that the feature belongs in the new Mail. I won’t get into what the feature is (it’s unimportant), but suffice it to say that many find the feature incredibly useful. It was shocking that we were spending any time at all in a meeting trying to convince someone that the feature belonged in the product.

As I said, however, the feature itself wasn’t important. We went into the meeting, armed with every reason in the world for why the feature belonged in the product. The opposition went into the meeting, armed with…nothing. In the end, we were struck down by the opposition. Not because they thought the idea was dumb or because they simply didn’t want the feature in the product. The one-line reason for not implementing the feature was that our competition (specifically citing a well-known competitor just up the road) didn’t provide it, so we didn’t have to either.

Frustration. Anger. Outrage. That sums up the range of emotions I went through.

June 2007

June was a pretty great month, the peak of 2007, I’d say. It started with a trip to London. I’d been dying to visit London. Yahoo! was already picking up the tab to fly me out there for work, so I took a week off and visited the sites. I spent the week crisscrossing London doing as much as I could. It was one of the best trips ever. London’s an amazing place and I can’t wait to go back and see the rest of the UK.

As I said, Yahoo! paid to send me to London. June marked the second Yahoo! Open Hack Day. It was a great event…an epic event. One of those times you’ll remember for the rest of your life. The perfect combination of people and places.

When I returned, it was time to move again. Back in April, Lisa and I found a new house in Santa Clara. The week after returning from London it was time to move into the new house. This move went much smoother than the move from Folsom down to the Bay Area. We knew what to do in order to keep the cats (relatively) calm.

August 2007

I officially transferred off of Yahoo! Mail in August. It was fueled partly by the desire to work on a new project, but mostly it was a desire to distance myself from Mail after what happened in April.

It may seem petty to let something like that affect me so badly, but oh well. It pissed me off. I didn’t come to Yahoo! to keep pace with the competition. I went to Yahoo! to bury them.

September 2007

September started out slow…too slow. Slow enough that I had time to think about it (big mistake) and write about it (bigger mistake).

In the end, I pulled myself together, reminded myself why I was at Yahoo! and put out my call to arms for fellow Yahoo!’s.

October 2007

October started with a trip to Chicago to speak at Adobe MAX. It was an interesting experience. I’m not sure how much people got out of my talk. My material seemed a little out of place given the topics in some of the other talks I attended.

Chicago itself was nothing to write home about. I was in the south side, which was a pretty “interesting” part of town to walk around in. Maybe my view is skewed because I was accosted on the streets by a drunk man in search of money to help pay his wife’s hospital bills. Money he later used to pay a woman for sexual favors, right after he offered to have her perform said acts for me.

October ended with a bang…or a shake. On October 30th there was a sizable earthquake centered within 10 miles of our house. The quake shook our house pretty good, knocked a few things down, but did no structural damage. However, it did scare the hell out of the cats. Ricky took it the worst, reverting to his misdirected aggression. He went after Lisa, more aggressively than when we moved from Folsom. He sunk his teeth into her leg and pinned her against the wall, refusing to let her leave. We finally managed to get him into a room all by himself and left him there to calm down.

November 2007

Unfortunately, Ricky didn’t calm down. Lisa couldn’t go into the room without Ricky growling, hissing and taking more swipes at her. We went through a lot of scenarios, trying to figure out what to do. A vet gave us some medication that we could give to Ricky, stuff that would calm him down. Even if we could get him to take it (we couldn’t), we couldn’t leave him on the medication forever. His aggression was getting worse with each episode he had. We were starting to get concerned that he might really hurt our other cat (Lucy), one of us or one of our guests.

It was the most difficult decision either of us has either made, but we decided to put him down. It’s been difficult since then. Ricky and Lucy were kittens when we picked them out in 2000. They’re like children to us. Having to give up Ricky so soon wasn’t something we ever saw coming. Having to put him down when he was in perfect physical health has been hard on the conscious, to say the least.

Around the same time, I hit my 3 year anniversary with Yahoo!. Having that coincide so closely with putting Ricky down is difficult. Yahoo! is the reason I moved back to the Bay Area in the first place, so I feel like my career is partly to blame for what happened to Ricky.

Near the end of the month I was moved to another project, marking the shortest stint I’ve had on any project (3 months). The new project came with a new title: local architect. I’m still figuring out what exactly that means and whether or not I like it. The verdict is still out on that one.

Looking forward to 2008

I find myself ending 2007 the same way I ended 2006, looking forward to the next year. I don’t mean to imply that 2007 was all bad. There were some great moments to be sure. Unfortunately, they’re largely overshadowed by some really bad moments.

And it’s been a long December and there’s reason to believe
Maybe this year will be better than the last

-Counting Crows - A Long December

See you in 12 months…hopefully with better news to report.

Low Fat Mail…rad!

December 4th, 2007

The Scottland University Hack Day sounded pretty cool…wish I could have gone. (Ahem…organizers…what has two thumbs and would gladly come to hack days in the UK? This guy. Just pick up the tab on my air fare)

Anyway, one of the hacks is called “Low Fat Mail”. It was built by some chap named Alex Mason. Alex…if you happen upon this post, I’d like to see it. I love seeing all the stuff built using the Yahoo! Mail Web Service. I admit, it’s a dense API. But if you can get through the initial shock of it, you can do some fun stuff with it.

BoxBe’s blowing up

November 30th, 2007

Wired wrote about BoxBe today. For those who don’t remember, I wrote about BoxBe a little while ago. BoxBe did their Yahoo! Mail integration using the Yahoo! Mail Web Service, which I was (until recently) the tech lead for.

BoxBe has been getting a lot of press lately, including a recent post on GigaOm. BoxBe is definitely the biggest application built on top of the Mail web service to date, so it’s exciting to see it get so much press. Way to go, guys!

I am so going to South Africa one day

November 28th, 2007

100mph zip line sort of says it all…

Get the source to my Yahoo! Mail Google Gadget

November 26th, 2007

After releasing my Yahoo! Mail Google Gadget available for people to check out, I had some people asking for the source. It seems they don’t trust me enough to run my gadget…they want to install their own. :)

In any case, the source is now available in zip and tar-gzip format. Have a go and if you manage to enhance it, drop me a line in the comments.

XMLHttpRequest::setRequestHeader()

November 17th, 2007

I’ve been working on rewriting a bunch of Air Mail lately. Partly because pieces of it (the ones I wrote) aren’t very good but also because I’m using it as an opportunity to reacquaint myself with some more heavy-duty DHTML coding.

One of the things I’ve been focusing on is the concept of having one codebase that works as both a desktop application in Adobe AIR and as a browser-based application served from a web server. This effort is worthy of an entire post on its own, but there is one thing that has been a particular pain in the butt…cookies (this is a recurring theme in my life, it seems).

Air Mail uses the Yahoo! Mail Web Service, which requires cookies to be sent in the request for authentication. In JavaScript, one of your only mechanisms for making web service requests is to use XMLHttpRequest. The XMLHttpRequest object provides a method named setRequestHeader, which allows setting arbitrary headers on HTTP requests. This should, in theory, allow you to set the “Cookie” header.

Theory, however, is often not reality. While this happens to work in Adobe AIR and Firefox, this doesn’t work in Safari, Opera or Internet Explorer (at least not in the versions I tested). Reading the specification for XMLHttpRequest, I don’t see anything indicating that the “Cookie” header ought to be restricted. I can only guess that Safari, Opera and IE are either buggy or decided to take some liberties (possibly in the name of security) when implementing the specification. If you’re interested, I have a test page that shows this issue in action. The page loads and makes an XMLHttpRequest to a page that does just echoes back the cookies it sees. If it works, you should see a cookie named “thisisa” with a value of “test” show up. In my case, I see it in Firefox only.

In any case, this does cause some complications for Air Mail.

Adobe AIR is able to send requests directly to mail.yahooapis.com. The web-based applications, however, have to send requests to ymail.unclehulka.com (the same host the web page is served from) due to the same-site restrictions imposed by the browser sandbox. I have an endpoint running on ymail.unclehulka.com that receives those web service requests and proxies them to mail.yahooapis.com. The code is identical, the only difference is the URL that Air Mail hits.

I’ve managed to configure the URL to connect to for the different application versions using GNU M4, but the cookies have been another problem. I’ve been reluctant to make two separate code paths for the different environments, simply because I think the single codebase is the most compelling feature of Air Mail. At this point I’ll likely move the cookie header name to an M4 configuration template. The desktop Air Mail will use “Cookie” as the header name. The web-based Air Mail will use “X-Cookie” or some other header not named “Cookie”, so XMLHttpRequest doesn’t prevent it from being passed. Then the proxy on ymail.unclehulka.com can simply copy that header to the “Cookie” header before sending the request on to mail.yahooapis.com.

Update: As Steve pointed out in the comments, there is a way around this issue in Internet Explorer…simply call setRequestHeader() twice. As I pointed out in my comment, I’m using the YUI Connection Manager, so I don’t actually control the calls to setRequestHeader() in this case.