Archive for May, 2008

The pain of project management

30 May

For the second time now, Grooveshark is making a serious effort to utilize project management software.

I don’t like the new project management solution, even though it is a vast improvement over the old one, and I think I’ve discovered why: I don’t like project management. I don’t like project management because project management is not for me; it’s for managers. Managers and developers have vastly different interests. Developers want to know what bugs are in their code, what features they need to develop, a way to view dependencies, and a way to see which bugs/features are most important. Bugzilla fits those needs perfectly. Managers, on the other hand, need to make sure that they are maximizing productivity by making sure devs are never sitting idle, they need to know what is going to happen when; they need ship dates.

The thing about bug tracking is that the people who benefit from it are the same people who have to do the work. If you want to see a bug get fixed, you file it. If you want to find bugs to fix, use the bug tracker. Project management tools, on the other hand, require a vast amount of work from the people who don’t need them: developers. That drastically decreases the chances that they will be used consistently. It also means that project managers end up working against their own goal: they reduce productivity. This is consistent with Le Chatelier’s Principle: Complex systems tend to oppose their own proper function.

It’s actually a more pronounced effect than just wasting dev time on project management. At least for me, having multiple people assign tasks to me with various arbitrary deadlines tends to make me feel like I am being micromanaged, which increases stress and also keeps me from being able to focus on any one thing for long enough to accomplish much. (“I’ve been working on this thing for 3 hours and I have all these other things to do, I should put it on the back burner and move on…”)

What’s the solution? I don’t know, but a good start would be to combine project management with bug tracking, ala FogBugz, set overarching deadlines for projects, let your devs work out the details, and be flexible. Plan for other things coming up, because new and very important bugs will pop up all the time, servers will break, and meetings will happen (sadly). If your developers are good, hardworking employees (and Grooveshark devs are), they will strive to meet or exceed the goals you set for them, without being micromanaged.


Grooveshark Loves Twitter

27 May

Largely due to the fact that so many Grooveshark employees use twitter, we have made a special site geared towards twitter users. (you have no idea how hard that was)

Anyway, we made Tiny Song: a simple way to get a short link to any song on Grooveshark. Just go there, type in the name of the song and the artist or album if you happen to remember it, hit enter and you’ll get a list of songs that match your search query. Click the song that you were looking for and get a short URL that links right in to Grooveshark Lite.

Here’s an example URL:


How not to do SOAP

24 May

If you are not already familiar with SOAP, this note will mean very little to you, and I don’t feel like explaining it so please feel free to ignore.

We are in the middle of adding a new payment processor to GS, and this particular payment processor, who shall remain unnamed, decided to implement their API in SOAP. I am not a huge fan of SOAP, but it certainly does have some level of usefulness: the entire backend API for GSLite is written in SOAP, after all. Anyway, their implementation of SOAP is the silliest I have seen so far. Every method takes a single parameter. It’s a string named ixml.

Can you guess yet what they are doing?

Yes, every parameter is a piece of xml. The actual structure of the xml message is not defined in the WSDL. In other words, the Web Service Description Language does not describe the web service. Good job, guys.


Linux: run script as a different user

22 May

In all the years I’ve been using Linux just enough to get by, I’ve never stumbled across this handy tip. If you have a script that, say, needs root access, but must be executable by users who do not have root access, rather than setting up sudo and then making everyone have to remember to type sudo before they type the path to the script, you can do this:

chmod +s filename

The script will run as the owner, and the permissions for executing the script will be determined by group membership. If you have a script that must be executable by users in the ‘devs’ group, but it must run as root, all you have to do is:
chown root.devs filename
chmod +s filename
(assuming your file is already group executable)

Obviously this file should not be group writable or you’re giving everyone in that group the power to run anything as root, simply by modifying the script and then running it.


Grooveshark Lite updates: More music, Better Popular List

10 May

Grooveshark Lite now has more music available for listening. I don’t know if I’m allowed to disclose totals, so I’ll just discuss the delta: about 400,000 more songs than previously available, all of them very high quality (> 256kbps). We were excluding them previously due to technical limitations, but those issues have now been solved. Enjoy!

Tired of seeing the same old crap on the Grooveshark Lite popular list? Well now you don’t have to. Previously, the popular list showed only the all-time popular music which was interesting, but obviously didn’t change much over time.

Our new algorithm calculates a normalized weight based on how many times the song has been played today, how many times it was played yesterday, and the total number of plays of all songs for both of those days. Songs that have a lower normalized weight than they did yesterday are penalized slightly. The net effect is that it’s easier for new songs to get on the popular list, and songs that are gaining popularity will be pushed higher up the list than songs that are becoming less popular.

If you take a look at the list of popular songs on Grooveshark Lite, you’ll see that our users have very eclectic tastes, which makes sense since our goal is to have a bit of everything, and that’s exactly what people are listening to. You’ll find just about every genre, new music and old music on there. At the time of writing, the second song on the list is a Katamari song!


Bad design

09 May

Bad design is everywhere, and it doesn’t have to be that way. I suppose that’s why I make such a fuss when one of our products or features seems to be poorly designed. I want to do better!

Here’s an example of bad design that isn’t our fault:
Everyone in the office has trouble using the coffee pot at one time or another. People get grounds in the water reservoir, overflow the basket, or get burned by steam when they open the lid. I have witnessed people do all of these things, and I have studied the design of the coffee pot. I understand how it works, but I still managed to overflow the basket myself, creating a horrible mess and (worse) delaying my caffeine intake. Why is this coffee pot so hard to use? My cheap coffee pot at home works just fine. I had no difficulties with the coffee pot at my previous job.

It’s the design. The basket and water reservoir are in the same “compartment”, covered by the same lid, and the component that stops the flow of coffee if the carafe has been removed (so you can pour a cup before it’s finished) is a mechanism that is half in the basket (spring loaded stopper) and half in the lid of the carafe (the shape of the lid pushes up the spring, allowing water to flow).

Every element of the design of this coffee pot is directly related to the ways that people manage to mess up their coffee:
If they are not careful about adding coffee to the basket, they will get grounds in the reservoir. The proper way to avoid that problem is to remove the basket, add the coffee and put it back in. The basket does not sit evenly on the counter because of the spring loaded mechanism on the bottom, so it discourages people from adding grounds this way.
Having one lid that covers the reservoir and the basket causes steam to be trapped in the coffee maker, so if people open the lid during the brewing process (say, because something else is messing up) or shortly afterwards (say, to clean up), they will have their fingers burned.
The spring loaded stopper does not stop the brewing process, only the dripping into the carafe process. If the stopper remains closed, water and grounds will eventually overflow the basket into the reservoir, into the carafe, and all over the place. The stopper remains closed whenever it is not in contact with the lid, so if someone accidentally leaves the lid off, or leaves the lid open “to make sure nothing gets in the way” (as one of our interns did), it’s an instant mess complete with ruined coffee.

Compare this to my coffee maker at home, the water reservoir is completely separate from the basket, which swings out on a hinge so that any spilled coffee grounds end up on the counter, not in the water. The mechanism that stops the drip process when the carafe is removed is a small lever that is depressed when the carafe is placed in the coffee maker. It stops the flow of hot water into the basket, thereby halting the brewing process whenever the carafe is removed.

This is an ideal design in every way, especially the lever to stop the brewing process. The only component required to let the water flow is the carafe, which catches the brew. If the carafe is not present, no coffee is brewed and no disaster ensues. Use of a lid is entirely optional.

So why is our coffee pot so horribly designed? It’s not like coffee pots are a new technology, and it’s not like they’ve just been this lousy all along, my coffee pot is older! They could have just copied the design if they couldn’t think of their own. I don’t see how the manufacture of my coffee pot style would be any more expensive than the one we have at Grooveshark. Mine was under $10, after all.

The only thing I can think of is that manufacturers just plain and simply do not care about usability for these essentially disposable appliances. Customers do not pay attention to these details until it’s too late, or they blame themselves for their inability to use them, so good design just does not matter.

But design does matter if your company is not satisfied with mediocrity. One need not look any further than Apple to see the result of putting a heavy emphasis on design and usability. The success of the iPod and iPhone are the direct result of that emphasis. If the iPod worked like a Sansa and the iPhone worked like my old Motorola phone, where would Apple be right now?



06 May

This is just a quick plug for an chat client I’ve just recently discovered: Digsby.

Digsby is a chat client that works with every network they can get their grubby little hands on. AIM, ICQ, Y!, MSN, Google Talk, Jabber, even Facebook chat. But there’s more, they also support email and Facebook, MySpace and Twitter. Twitter has always seemed well, rather useless and annoying to me, but having it integrated into a desktop client and on my phone means I might actually use it.

I know what you’re thinking: Trillian does a lot of that. Well, yes, but digsby seems well designed, less clunky and annoying, and ironically more stable, even though it’s far newer and does more.

Another bonus with Digsby is that you create a profile on their site, so when you sign in on another computer, you don’t have to set up all of your accounts again.


Always test in context

03 May

When testing your work, it’s essential to always test it in the context that it’s going to be used in.

Last weekend, I helped a friend move her stuff down to the Orlando area. UHaul trailers are incredibly cheap compared to trucks, and my car has a hitch, so we got one of those, loaded up her stuff and headed south. Somewhere along the way, the hookup for the lights became disconnected and then dragged along the ground, getting all nice and melted in the process. I noticed this when we got to her new apartment and called UHaul. Awesomely, they have free roadside assistance for any time something happens to their trailer.

They sent out a guy, he looked at the hookup on the trailer, rewired it, and tested it with his wire testing doohickey before taking off. We had already disconnected the trailer from the car for parking purposes, and when he pulled in to fix the trailer he blocked access to my car, so we didn’t actually hook it up to my car to test it.

A few hours later, it’s time to go home and return the trailer and oh, crap, the lights don’t work. I had to call UHaul and have them come fix it again. Because of the way the trailer was hooked up originally, the tongue of the trailer managed to get on top of one of the wires on my side of the connector and eventually wore through it, something I hadn’t noticed previously. It also managed to blow a fuse at some point so my brake lights didn’t work at all even when the wiring was fixed. Fortunately, the UHaul guy was very friendly and also had all the parts one could ever need for fixing minor car problems, so he easily re-rewired the connections and fixed my fuse.

Still, a few extra minutes of checking the trailer in the context it was going to be used in (i.e. attached to my car) would have revealed the problems and saved UHaul several hours worth of labor (driving to and from the apartment complex; they were far away).

That was a non-technical example of the principle, but there are certainly plenty of technical ones as well:
When I wrote the code to handle our PayPal processing, PayPal helpfully provided a development sandbox for testing with. All my code was thoroughly tested, seemed to be handling every sort of error that I threw at it, processing successful charges properly and everything. Then when it was time to release we pointed it at the ‘real’ PayPal servers and suddenly it didn’t work anymore. A few (real) payments later and some minor differences between how the real servers worked and how the dev servers worked were revealed. No big deal, but again, some testing up front in the correct context would have prevented the issue from ever appearing in the first place.