I installed Jinzora, a music organizer/streamer/jukebox application, today. I have some interesting impressions. Quick summary: I’m not going to use it because it’s technically deficient.
This isn’t really a comprehensive review, just an exclamation over the techniques involved in the implementation of the software.
Jinzora is a PHP+Apache+(MySQL/Postgres/SQLite/etc) application that indexes and manages your music library, and provides streaming access to said library over a network. It’s a great idea — you can have a music server set up in the house and let satellite computers stream a music library from the network, without needing to set up anything aside from a webserver. Jinzora can also be configured as a jukebox such that (if the hosting computer has speakers) you can remotely control playback of any of your music.
The setup was fairly straightforward. There were a few technical issues configuring PHP to have enough memory and enough execution time to run; it certainly isn’t a plug and play experience. Specifically, for Jinzora to run well, it requests longer than 300 seconds on max execution time and 32+ megs for a memory limit.
Those two things gave me worries, because typically upping the execution time and memory limit are the lazy programmer’s way out. I actually did bump into a memory limit during the import of my music library and had to set it to 128M for things to go through.
Aside from that, the web-install was fairly easy. There weren’t any technical issues that stopped the show (aside from needing to bump up the memory limit). When the importer encountered oddly tagged or oddly named files (with special characters or whatever), it did throw errors, but it kept going. It took approximately an hour to import 15,000 files.
Once it was running, I was pleased with some neat things it provided: there are related artists links for any particular track/artist. These are broken apart into artists you have and ones you don’t. Searching seemed to work reasonably well. Streaming worked without a hitch — clicking a music link prompted me asking if I wanted to play what the site was sending (it sends .m3u files, so they should be playable by most modern music players.)
It finds album art if there is art in the music directory in question. I think there’s some mechanism for grabbing album art from external sources, but couldn’t find the setting.
You can configure Jinzora to send useage reports to last.fm if you use their services.
Unfortunately, I didn’t fully explore this application due to the one showstopper.
The showstopper, and reason why I won’t be using it, is this:it is insanely slow.
Granted, the machine I ran this on was a PII 300 w/ 256M RAM, but even so, it felt as if the application were iterating over the file structure each time I loaded a page. Page loads literally took up to 30 seconds to load. For comparison, a simple rails application I wrote, working from a MySQL database over the same library, took half a second to load (with the crappy Rails paginator, no less.) As well, a PHP-based indexer I wrote that actually traverses the directory on each page load takes only 10 seconds to load. I realize that the hosting machine is crap, but it’s not that crap. Something is definitely wrong with the code.
(This is where it gets a little more technical.)
So… I looked at the database Jinzora set up to see if I could optimize with indices or something. There are indices. The fields they are indexing are varchars. In fact, every single field is a varchar in any of the tables, with the exception of playcounts.
The primary key is a varchar. I repeat: the primary key is a varchar!
In despair, I looked at the PHP to see how rough it would be to fork Jinzora for proper design and normalization.
Every select that used the primary key (which was called ‘path’ and used the file’s path, btw) used the LIKE statement. There was nothing that looked like a JOIN statement (and come to think of it, I don’t really know if you can join on text fields in all the databases it supports.)
Every single SELECT looked something like “SELECT foo WHERE path LIKE ‘$path%’ “. It’s not just using text fields to index, it’s using LIKE, which is perhaps the slowest mechanism for accessing data in a database!
Searching on the net, I found some forum user asking how to speed up Jinzora. He reported that he was seeing 150 queries per second. FOR A SINGLE PAGELOAD.
No wonder my experience was so slow. (Aside: Actually, it’s kind of supportive of the Linux system’s configuration and PHP’s performance that it didn’t take 5 minutes to load with that kind of crap going on behind the scenes.)
Anyway, that was my experience with Jinzora. I saw a Google cached post that hinted at database normalization in version 3, so maybe I’ll return to it at a later date. For now I’ll just write my own.