RSS
 

Archive for the ‘Uncategorized’ Category

Bugzilla error

23 Sep

Setting up Bugzilla for a friend on a slicehost account running RHEL5, I ran into issues following the official installation guide.
After running:
./checksetup.pl --check-modules
/usr/bin/perl install-module.pl --all

The error message I received was:

Can’t exec “–decompress”: No such file or directory

Amazingly, I found no exact matches for this in Google (my google-fu is generally weak, however). It turns out that in order for the module installer to be able to install the modules it needs, there’s a certain module it needs!

yum install perl-Compress-Zlib.x86_64
yum install perl-Archive-Tar.noarch

makes everything happy again.

Nothing earth shattering, but maybe now Google will have an answer if anyone else runs into this.

 
 

Free eBook for VIP users

01 Sep

…sorta.

It looks like there was a mix up and a bunch of our VIP users received the following email:

Andrew Wise
to me

show details 2:10 PM (3 minutes ago)

Hi,

Thanks for purchasing our eBook, please download the eBook from this email.

http://tripletsmommy.com/wp-content/themes/typebased/ebook1.zip

Having not actually purchased an eBook, some of our users thought this was a weird form of spam or phishing, or even that their accounts might have been compromised. It’s nothing as sinister as all that, however, just a flub.

Here’s the official explanation from BWC, sent to one of our users who originally pointed out the issue:

Hey [redacted],

Thanks for letting me know, and sorry for the confusion!

Looks like our business guy (Andrew) who handles all our PayPal and such had a little mixup between Grooveshark and one of his side-projects. I just yelled at him, and everything is sorted out now.

[...]

Let me know if there’s anything else I can do to help out. Oh, and I guess enjoy being a triplets mommy! ;)

Regards,

Ben Westermann-Clark

 
 

Manage Your Library

21 Aug

Coming to Grooveshark 2.0 is the ability for users to add music to their library without uploading, and without even scanning in their library.

That’s right, if you find a song on Grooveshark that you like, you can add it to your library with the simple click of a button. If you have a song in your library that you wish would just go away, you can also remove it from your library with the simple click of a button.

Screenshots:

You can click this button on any song row to add it to your library (note: icon subject to change)


You can also drag as many songs to your library at once as you’d like.


If you toggle this button (icon subject to change) when it is highlighted, the song will be removed from your library.

Reminder: We will be releasing a preview (in other words, still buggy) version of Grooveshark 2.0 to VIP subscribers on the 24th, this upcoming Monday. Subsequent changes to Grooveshark 2.0 will depend on feedback we get from the VIP community, so we can’t predict when 2.0 will be available to the general public.

 
 

New RPC Server

20 Aug

Among the many backend enhancements coming together for Grooveshark 2.0 is a brand new RPC Server that I wrote. The format it follows is the same as the last incarnation, JSON, but it’s considerably more efficient.

First, a history lesson. Our first stab at RPC (codename tambourine) was SOAP. We chose SOAP because it did what we needed (theoretically), it was XML (so super easy for Flash to use), and it’s also super enterprisey, which appeals to certain people here, myself not included. We used NuSOAP because it supports WSDL generation, which is so annoying we did not ever, ever want to have to do that by hand. Using SOAP turned out to be a huge mistake (anyone familiar with SOAP probably could have told us that). Because it’s XML, it was super easy to break the service by returning data with, say, an unsupported character in it, or by having PHP accidentally output a newline character (say, by following the PEAR standard and having an extra newline at the end of every PHP file). Further, because browsers eat most error codes and don’t pass the codes or the accompanying data on to plugins, we had to hack NuSOAP to violate SOAP standards and return a 200 OK when generating SOAP Faults. On top of all that, and most importantly, it turns out that generating all of that XML is very expensive. So expensive that I could not test code locally on my machine before putting it on a server. So expensive that we actually got a huge performance boost by caching the generated XML in memcache.

After the SOAP fiasco, we wanted to try using JSON, because it’s much more terse and far less expensive to generate than XML, while still being human readable, which we value for debugging purposes. We looked at official JSON-RPC stuff, but we were spoiled by SOAP in one regard: support for headers. We got used to using headers to pass around status information that didn’t exactly belong to the method calls, and we didn’t want to give that up so I wrote my own JSON-RPC server (codenamed cowbell) modeled largely after how SOAP worked, but more efficient. My custom JSON server class was only 275 lines long to NuSOAP’s 7,994 lines for just the core file. We gave up the elaborate data type declarations (we just verbally communicated what type everything would be), but beyond that method registration worked the same way as SOAP and every other RPC implementation I’ve seen: you need a service file which registers all available methods with the RPC server, and then invokes the RPC class, passing through the raw POST data. Although I did not save benchmark information, the speed difference between my custom RPC class and NuSOAP was astronomical, so we left the RPC optimizations at that.

I recently came back and did some profiling out of curiosity to see how much overhead our current RPC implementation was creating, and it turned out to be about 15% plus about an extra 1.5MB of memory used. I thought about how things were working with the current implementation and realized that it’s a bit silly to be registering hundreds of methods every time the client makes a request, when you really only need information about whatever method is currently being requested. All the other information is superfluous. So in our new JSON-RPC implementation (codename more because it’s still cowbell in a way), 162 lines long, there is no ‘registration’ of methods. Instead, the service class that would normally do the registration simply has a collection of “meta methods” which return information about the methods that make up the service when called. So the RPC server parses the request, does a little bit of reflection magic to determine which meta method to call, and calls that method to get all the information it needs in order to handle the request. What’s the overhead of this approach? Well, it hardly even registers in the profiling I’ve done. :)

In summary, Grooveshark 2.0 method calls should be nearly 15% faster on average than Grooveshark 1.0 calls. :)

P.S. On the topic of cowbell, there’s an old easter egg that we added and never got around to telling anyone about. Before Grooveshark 2.0 is lost and it’s forgotten forever, you can get to it by typing about:cowbell into the search bar.

 
 

All /sorts/ of Improvements

19 Aug

I mentioned in Bypassing Magic that Grooveshark 2.0 will be loading much larger data sets, and one consequence of this is that the application can do more with that data.

As you might have guessed from the punny title of this post, one of those cool things is sorting! When looking at a list of songs, artists, albums, etc., in Grooveshark 2.0, you will be able to sort that data however you like.

Yes, this is another excuse for me to leak a screenshot. ;)

Grooveshark 2.0 Sorting

Another feature it enables which won’t make it into the VIP release of the 24th, but will be available to VIP users shortly thereafter, is live search. You’ll be able to narrow down any list of songs you’re looking at by searching within the result set.

 
 

Ghost Glacier

18 Aug

Some of my favorite music also happens to be made by some of my friends. :) Please enjoy Ghost Glacier.

 
 

Better Playlist Editing

16 Aug

Ugh, we know, in Grooveshark 1.0 it is a royal pain in the ass to edit playlists. For various reasons the playlist editing system in 1.0 is a hack on top of a hack. For Grooveshark 2.0 the playlist editing system has finally been rewritten. Aside from a brand new, far less annoying interface, the actual mechanisms for modifying a playlist are vastly improved.

In Grooveshark 1.0, the way most people edit a playlist is to load it up into their queue, most songs around in the queue, add new songs to the queue, etc., and then save the queue, overwriting their existing playlist. If you just want to change the order of your playlist, technically you can do so by opening the playlist page, and clicking the up or down arrow to move a song up or down one position at a time. That means if you have a song in position 10 and you want it to be the first song on the list, you have to click up 9 times.

In Grooveshark 2.0, playlists fully support drag and drop actions. You can still save your queue as a playlist if you like, but you can also edit a playlist by dragging songs into it, dragging songs to the trash to delete them, and moving songs up and down on the list by, you guessed it, dragging them!

Here’s a screenshot with drag and drop in action.
Grooveshark 2.0 Drag and Drop playlists
Click to see full size

 
 

However you succeed, you will die

13 Aug

Mark Cuban recently wrote an article titled When you succeed with Free, you are going to die by Free.

Lets look at the rule that eventually KILLS all freemium based content plays:

There will always be a company that replaces you. At some point your BlackSwan competitor will appear and they will kick your ass. Their product will be better or more interesting or just better marketed than yours, and it also will be free. They will be Facebook to your Myspace, or Myspace to your Friendster or Google to your Yahoo. You get the point. Someone out there with a better idea will raise a bunch of money, give it away for free, build scale and charge less to reach the audience. Or will be differentiated enough, and important enough to the audience to maybe even charge more. Who knows. But they will kick your ass and you will be in trouble.

What’s the difference in this equation between free and non-free services? Does being non-free insulate one from competition?

Let’s imagine a world where search isn’t free. Google search is so good that they have killed off all of their competitors, and they decide to start charging $5 a month for everyone to use it. People pay because hey, Google always finds what they want and what else can they do? In this very imaginary scenario, Google’s black swan would be any other remotely decent search technology provided that it is offered for free. The point of this extreme example is that Google is more insulated from competition by already being free, so the above argument is silly.

The rest of the article goes on to say that no matter what type of service you offer, you should be on the lookout for your black swan and when it arrives, assuming you can’t purchase it, you should take all the money you’ve earned and run, rather than stay and fight an expensive losing battle. (I’m oversimplifying quite a bit, mostly because this isn’t the part that I care about)

That’s…fine, although I don’t necessarily agree on that point either, but Mark attacks some of the commenters in his blog for picking on the “free” aspect of his blog post like I am doing here because they miss the point at the end about how cutting and running. Perhaps if he had stuck with his original intended title “The Freemium Company Lifecycle Challenge” he wouldn’t have caught so many peoples attention and it would have just blown over. But if he really didn’t want these disputes popping up, a better title would have been “Everyone has a Black Swan, the trick is recognizing and reacting,” or something, you know, actually related to the true premise of the article. ;)

 
 

Not giving you the password

06 Jul

Raymond Chen’s post about passwords reminded me of a humorous* java exception I frequently experience when trying to do something in the Palm Pre developer section:

java.lang.UnsupportedOperationException: Not giving you the password
com.atlassian.crowd.integration.acegi.user.CrowdUserDetails.getPassword(CrowdUserDetails.java:52)
org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices.makeTokenSignature(TokenBasedRememberMeServices.java:285)
org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices.autoLogin(TokenBasedRememberMeServices.java:240)
org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:104)
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
com.jivesoftware.community.web.filter.ApplicationStateFilter.doFilter(ApplicationStateFilter.java:112)

“not giving you the password” — not only is this phrase funny as an exception, but it clearly looks like someone is doing it wrong. No, you shouldn’t be requesting the actual password in order to get a “remember me” type token. Of course, they’re doing a lot of other things wrong too, like showing this error to the user, and apparently not alerting themselves to the error, as I’ve been getting it off and on for several weeks at least.

*and, yes, annoying when I’m trying to actually accomplish something

 
 

Grooveshark has outgrown Gainesville

04 May

We have just about completed moving all of our servers from Gainesville to Colo5 in Jacksonville. Why did we have to move? Bandwidth! We simply could not get a fat enough tube to handle all of your music streaming demands into Gainesville. Why Jacksonville? Because it’s cheap, and close! We were considering moving to a similar facility in Atlanta, but Colo5 came in cheaper, while offering the same sort of bandwidth that we could expect to get in Atlanta. How much bandwidth? We should have room to grow up to about 20Gbps before we will have to consider expanding to other facilities. We’re going to need a lot more servers before that can happen.

Although we now have plenty of bandwidth for the near to mid-term future, there are still plenty of other bottlenecks that are starting to pinch us, so don’t be surprised if playback is still laggy sometimes or results to buffering. The next big improvement we need to make is the “bandwidth” we get from our disks. No point having 20GBps of headroom in the tube if we can’t actually get that much off of our servers. We have several strategies we are applying to this end, and I may post more about them later if I have time.

The transition from Gainesville to Jacksonville was, of course, not as smooth as we had hoped. Everything was going along swimmingly until we went to install our crappy “downtime server” in Gainesville to let users know that we were down and why, while allowing us to take the real web servers with us. The server and router simply would not acknowledge each other’s presence. Our laptops could connect directly to either one just fine, but both thought they had no connection when interfacing directly. The solution? A crappy old Linksys hub, which both the router and server were able to see.

Loading up all of our servers containing all of our data into a UHaul was more than a little scary, but we packed everything very carefully using lots of cardboard, furniture blankets and rope. Not a single server was harmed in the moving process!

Ben got a lot of pictures of the whole event, if you’d like to see more. Big thanks to Ed, Skyler, Joe, Colin and Nate for all working so hard to make the transition as quick and painless as possible, and thanks to Paloma for driving us home and letting us sleep on the way back; we were definitely in no shape to drive after all that.