Tuesday, February 26, 2008

How to Rip mp3's in Ubuntu 7.10

Here is the easy version:

sudo apt-get install gstreamer0.10-plugins-ugly-multiverse

Then start up the pre-installed CD Juicer application. Go to Edit/Preferences, you will now see an mp3 option there.

Note that I already had lame installed, so you might need to do that (sudo apt-get install lame).

Monday, February 18, 2008

MonoTone with FastAGI

I'm doing a lot of IVR work with MonoTone using C# under Mono deployed to Linux. I used the MonoTone library, and implemented by own FastAGI library. I'm considering releasing this as open source, but I'm not sure if anyone else would be interested. I realize there's another C# library out there, but I didn't like it much.

Mono performance with Timers

Am I just imagining things, or does a basic C# Mono application that uses Timers "leak" CPU time? I have this application that spends most of its time idle. I added in a part that triggers a timer once per day. Now the application twiddles away tiny bits of CPU time from 0.3% to 1% pretty much continuously. After a few days, it's got many minutes of CPU time accumulated.

Normally I wouldn't worry about it. But this application is running on a machine that uses Asterisk, and voice quality is of paramount importance. So I want that machine running as lean as possible.

Update: I found that I had a
#define TRACE
in my code, because I'm using a trace listener for logging. The .NET docs say that you need a #define TRACE for trace listeners to work. Turns out, you really don't. Trace listeners still work without that. And for some reason, the application takes a lot less CPU time without that, but still works.

Don't Catch Exceptions Overzealously

Software Lesson learned today: only catch exceptions you expect.
Let’s say you have a method called UserFind(userid) that looks for a user and throws an exception if not found. Don’t do this:
Try
{
User x = UserFind(userid)
}
catch
{
showError(“User not found”);
}

If something funny happens, like your database changes a column name, then you’ll never know what happened—it’ll just say user not found.
While it’s more work, you really need to create a DataNotFoundException and throw that in the UserFind.
And make it like this:
Try
{
User x = UserFind(userid)
}
catch (DataNotFoundException)
{
showError(“User not found”)
}

This way if you change a column name, you’re catching a DataNotFoundException. But if you get a SqlException, you will let it pass and crash the application.
“OMG, I don’t want my application to crash!” Well, of course you don’t. However, if someone changed a column name, you’ll find out about it a and find out the cause lot quicker in testing this way. Besides, your application shouldn’t crash anyway, it should just be crippled for that part of your program. And it already was anyway, you were just hiding the fact.

I really already knew the “correct” way to do exceptions was to make small grained exceptions and filter this way. But it just seemed like so much extra typing that I typically didn’t do it. And really I would like it if I could declare the constructor that takes a string for the exception with less boilerplate repetitive code… Ruby style metaprogramming would be great for this. I’d just say something like “declare_exception DataNotFoundException, DataException”. But then Ruby’s deal with not automatically calling the base class constructors really ticks me off…

Heap Buddy with Mono on Ubuntu

I had some memory leaks going on in a C# application, and wanted to dump the heap objects the way I used to in .NET under Windows. Here are notes of what I had to do to get Heap-Buddy working with Mono under Ubuntu 7.10:

mono c# heap dump
you want heap shot from here http://www.mono-project.com/HeapShot
to compile I needed to install:
sudo apt-get install libglib2.0-dev
sudo aptitude install subversion nant mono mono-gmcs libmono-microsoft8.0-cil libmono-system-runtime2.0-cil
sudo mv /usr/local/lib/libmono-profiler* /usr/lib

mono –profile=heap-buddy:x.out datingline.exe -a
heap-buddy x.out types

Legacy Code

I've been thinking a lot lately about C++ and its level of "cleanness" and suitability for some new projects I'm doing. I ran into this quote from Bjarne Stroustrup about legacy code:

"Legacy code" is a term often used derogatorily to characterize code that is written in a language or style that (1) the speaker/writer consider outdated and/or (2) is competing with something sold/promoted by the speaker/writer. "Legacy code" often differs from its suggested alternative by actually working and scaling.