iTerm 0.9.6.20090209 is Out

February 16th, 2009

iTerm.jpg

Found out today that iTerm 0.9.6.20090209 has been released with a few bug fixes on the rendering of bold text and a permissions issue. Nothing major, and while it's nice with it's ability to add the window border on the bottom (or not) and the ability to remove the scroll bar, I'm thinking it's still not ready to replace Terminal.app because of the window sessions.

Still... maybe it's something to suggest to the developers? Might be worth a try.

Looking at Atomic Operations for Lockless State Management

February 13th, 2009

cplusplus.jpg

I was listening to an interesting podcast today about lockless state management with atomic operations and got to thinking that there's a lot this can be used with if you spend a lot of time to get things into simple word-sized blocks. But there's a ton that can be done just as-is.

What I'm thinking about right now is the simple retain/release counters that I have on my instrument objects in the fast-tick server. Face it... they are about as simplistic as you can get. This article by IBM talks about the atomic operations in linux, and looking at a few include files, I can see that it's supported in the version we're using simply by including asm/atomic.h. Good news.

What I'll need to do is read up more on this and see if I can fit these easily into the retain/release code. If I can, then it's probably worth trying. The number of times I hit that code is non-trivial, and that's all kernel-space work. Better to be in user-space and not have the overhead. The code I have now looks a lot like this:

void Instrument::retain()
{
    // first, lock this guy up
    CKStackLocker      lockem(&mRetainReleaseMutex);
    // no up the count
    ++mRetainReleaseCount;
    // see if it's in the pool to be released, if so, remove it
    if (mRetainReleaseCount == 1) {
        CKStackLocker      lockem(&mReleasePoolMutex);
        mReleasePool.remove(this);
    }
}
 
void Instrument::release()
{
    // first, lock this guy up
    CKStackLocker      lockem(&mRetainReleaseMutex);
    // no decrease the count
    --mRetainReleaseCount;
    // see if it's an error
    if (mRetainReleaseCount < 0) {
        getLog() << l_error.setErrorId("Instrument.release")
                 << "the release count for " << mmSym() << " went negative! ("
                 << mRetainReleaseCount << ") This is a serious problem." << endl;
    }
    // see if it's at zero, and then if so, add it to the pool
    if (mRetainReleaseCount <= 0) {
        CKStackLocker      lockem(&mReleasePoolMutex);
        if (!mReleasePool.contains(this)) {
            // log that we're going to dump it in the trash
            getLog() << l_error.setErrorId("Instrument.release")
                     << "adding " << mmSym() << " with retain cnt="
                     << mRetainReleaseCount << " to garbage" << endl;
            // ...and then do it.
            mReleasePool.addBack(this);
        }
    }
}

The trick will be to do the entire method atomically. I can't just change the count. The checks are also critical, but maybe if I do the change, and keep the flag, that will work. Problem might be that another operation gets in the and wants to undo my work, but I come later... it's not an easy problem to solve with a single atomic operation on an int.

Certainly something to think about.

Software Updates: Java for Mac OS X and Security Update 2009-001

February 13th, 2009

Leopard.jpg

This morning I noticed that Apple had released two updates on Software Updates: Apple Java for Mac OS X 10.5 Update 3, and Security Update 2009-001. The Security Update is pretty obvious - there's a few underlying libraries that have exploits in them and these are the patches. I've read that it includes the Safari RSS security problem written up a while ago. Good enough. The more interesting one to me is the update of Java.

It's supposed to update the Java WebStart which is interesting as I've been using it for quite a while now, and I'm convinced that it's a valuable way to deploy a Java app to remote sites with auto-updating. Very slick. Also, they are supposed to have worked on the applet functionality. Again, good news.

So it was a reboot, and that's a pain, but maybe someday they'll have a "restore state" for the entire login and then it won't be so bad. Yeah... that would be very nice...

MarsEdit 2.2.3 is Out!

February 12th, 2009

MarsEditIcon128.jpg

While it's not a major update, there are a lot of bugs in the version I was running, and so Daniel J. released an updated version of MarsEdit that addresses the biggest offending bugs he's come across in the past few months.

I think I'm going to like a few of these features on the preview pane, but I'll certainly be looking forward to the next big release with lots of cool, new features.

Cleaning Up the PrettyPrint in Python’s xml.dom.minidom

February 12th, 2009

python.jpg

OK... well, this has been an interesting exercise. I've been working on a Python script to grab data out of a system here, and generate an XML file for a vendor upload. It's a big file, and there's a lot of things that have to go into it, but I wanted to be able to do as much as possible from within the Python code itself. If I had to post-process it and add tags later, then that's OK, but I didn't want to start with that plan. I wanted to make the utmost of python's capabilities for this task.

For the most part, I haven't been disappointed. Python has a pretty nice XML DOM system (xml.dom.minidom) built-in, and I was able to create the document very easily. The problem came in dumping it to a file. There were two basic ways I could dump it:

<exchangeTraded><id type="SEDOL">B10RB15</id>
<positionName>1605=JP</positionName><amount>-214.0</amount></exchangeTraded>

where it all appeared on one 'line' and no spaces were to be found, for the 'simple' XML output, and:

<exchangeTraded>
    <id type="SEDOL">
        B10RB15
    </id>
    <name>
        1605=JP
    </name>
    <amount>
        -214.0
    </amount>
</exchangeTraded>

for the 'Pretty Print' output. Neither was really good, but as the lesser of two evils, the second one was far more readable for the size of the file I'd be sending. But I knew that I needed to get back to this as soon as reasonably possible and fix this up with a decent output processor.

Today has been that day. I was quite lucky that I got a good head-start with Google, and was able to put together the following replacement for writexml():

def new_writexml(self, writer, indent="", addindent="", newl=""):
    # indent = current indentation
    # addindent = indentation to add to higher levels
    # newl = newline string
    writer.write(indent + "<" + self.tagName)
 
    attrs = self._get_attributes()
    a_names = attrs.keys()
    a_names.sort()
    # lay down the attributes on the tag
    for a_name in a_names:
        writer.write(" %s=\"" % a_name)
        xml.dom.minidom._write_data(writer, attrs[a_name].value)
        writer.write("\"")
    # now lay down the child nodes
    if self.childNodes:
        if len(self.childNodes) == 1 and \
                self.childNodes[0].nodeType == xml.dom.minidom.Node.TEXT_NODE:
            writer.write(">%s</%s>%s" % (self.childNodes[0].data, self.tagName, \
                        newl))
            return
        writer.write(">%s" % (newl))
        for node in self.childNodes:
            node.writexml(writer, indent + addindent, addindent, newl)
        writer.write("%s</%s>%s" % (indent, self.tagName, newl))
    else:
        writer.write("/>%s" % (newl))

where the arguments are exactly the same as the original version, we've just cleaned up the printing of the child nodes when there's only one and that one is a text field. To install it into the proper place in the runtime, I simply need to:

#
# This is the main working section of the script
#
def main(argv):
    # hook in our new XML DOM writing code
    old_writexml = xml.dom.minidom.Element.writexml
    xml.dom.minidom.Element.writexml = new_writexml

and it's good to go with the same old code.

The results are perfect:

<exchangeTraded>
    <id type="SEDOL">B10RB15</id>
    <name>1605=JP</name>
    <amount>-214.0</amount>
</exchangeTraded>

I'm sure I'll be using this again very soon, and I wanted to document it so I didn't forget it. Really quite simple, but the effects are quite dramatic on a large file with thousands of nodes.

Pleasantly Surprised with Python Today

February 11th, 2009

python.jpg

I've been writing an XML file generator in Python hooking into a few data sources (systems) here at the Shop. I'm really quite pleasantly surprised at how easy it is to do all the little things you need to do. Formatting, logging, database, it's all there. With a decent access to the data, and a nice object model, it's downright pleasant.

I have to admit I'm surprised. I expected a more 'stripped down' language than this has shown itself to be. Yes, it's supposed to be all wonderful and that, but until you really need to dig into it, refactor it, and do all the little things that you're not going to find in a simple 'Hello, World!' app, you can have your doubts, as I did mine.

The object model is nice, if not a little confusing. The proliferation of self is a trifle annoying - can't this be inferred from scope? Maybe not. It's something that I can get over, but it is a bit odd at first.

The indenting at least makes things look nice. The speed is first-rate, I'll give you that. There isn't anything I can complain about there.

If I spent a lot of time in it for a few weeks, I'm sure I'd pick up a lot of habits that would make it very nice to write in. Libraries, or finding those libraries like the XML DOM, are real time savers, and yet it takes time to look them up, learn how to use them, etc. Time worth spending, but time you need to spend.

I have to say... it's not PHP, but it's really quite nice.

Disappointment in Subversion’s Schema Changes

February 11th, 2009

svn.gif

I was working with a subversion workarea (the check-out of the repository) today and tried to do a simple 'svn status' and got the following on the console:

  svn: This client is too old to work with the working copy '.';
      please get a newer Subversion client

What?! I had been using subversion version 1.3.2 (FedoraCore 5) for a while, I've used 1.4.4 (Mac OS X 10.5.6), even 1.4.3 on a shared install for Linux at the Shop - but I've never seen this.

So I do some digging. First, upgrading the FedoraCore 5 subversion install to 1.4.x is virtually out of the question. There are so many links to that RPM that it's possible to build from source and put it in /usr/local/bin/, but it's just as easy to soft-link the shared drive version (1.4.3) into /usr/local/bin/ and leave it at that.

So why the horrible upgrade path? Sure, subversion uses the apache libraries and such to provide functionality so that they didn't need to write it. That makes sense - to a point. But if I have links to 50 different shared libraries and I want to update my source control client - I shouldn't have to upgrade my OS. It should be something relatively simple. But it's not.

OK, RedHat (Fedora) can take a bit of the blame and the package management. But not all. There's not reason for this. CVS doesn't need it. Git doesn't need it. There's nothing that requires it. It's just the way they decided to do it. Freeze subversion at the OS level (by RedHat), and build it on so many shared libraries (subversion). Together, they make it ridiculous to upgrade the subversion client on a Fedora Core box.

But the big issue was not that the update was exceptionally hard, it was that is was required at all! What were they thinking? Honestly. What version control system makes a repository or workarea schema change that locks out an older version of the client? Amazing. I understand that they are trying to bring better features to the system. That's great. But they have a schema that's been established for a long time. They decide to change it now? I'm blown away.

Don't get me wrong. I understand progress. I understand new features. Xcode updates the old files and makes them unreadable by the previous version. Got it. But Xcode is not a source control system. The problem domain didn't change on them. If that didn't change, they they either did a very poor job putting the schema together in the first place, or they believe source control needs to have new bells and whistles for some reason.

In either case, I am re-affirming my stance with subversion. Won't use it except where I'm forced to. And then, only if there's no possible better alternative. CVS still wins, in my book, for centralized SCM, and Git wins for decentralized SCM. This isn't something that needs to have fancy new features. You need to have stability and reliability. Period.

Want to change the schema? Fine, make it part of the schema - XML does it. Then the client doesn't have to change as it reads all the descriptive information about the repo at runtime. Again, the client doesn't need to change.

I am forced to believe they are either poor designers or interested in shiny buttons. Neither of which is never a good thing. More than anything else I'm stunned that they'd mistakenly design the schema. This was an update of CVS, they knew all the 'limitations' of CVS, and set out to 'fix' them. That they missed the primary reason for source control -- stability, is beyond me. It's just amazing.

I'll keep my distance from subversion, thanks. There are plenty of other, better, alternatives out there.

Sometimes It’s The Smart Person that Walks Away

February 11th, 2009

cubeLifeView.gif

Over the course of the last few months, I've had a few run-ins with a co-worker and while I initially put it off as a bad manners, lately, I've come to realize that this person is really exceptionally rude - yet thinks of themselves as humorous.

I'm sure there are literally thousands of people we all meet every day like this. They believe that the way to establish some connection with a person is to prod, poke fun, and then with a wink and a nod, let that person know that they aren't serious. To a point, this is understandable. People can be nervous in all manner of ways, and this can manifest itself in a lot of weird behavior, but when this goes too far, it's really quite counter-productive to the work environment.

Unprofessional Behavior. That's what it is. Simple as that. Out on the street, you are free to be as rude and nasty as you can stand. Doesn't make it right, just means that no one really has to deal with you - but you. But in a work setting, this is not really helpful. I've probably made it worse by allowing it in the first place. I should have just spoken up and said "Hey, funny 'Ha ha', but please, let's keep it professional, OK?"

Unfortunately, I've had to get far more blunt with some folks I've worked with. Sad that they didn't take the more mild hint, and I've had to actually say "You're making fun of me, right?" and when they agree, I say "Have you no shame? Please stop." I've been lucky - that usually does it, but in some cases, it's best to just walk away.

There are people that believe they know you, that they are you buddy, and so they say these rude things, as if to say "Hey, you'd only let a friend do this - right?". Wrong. I would never let a friend do that, and I'd never do it to a friend. What kind of friends do you have, anyway? Convicted felons and Wanna-be Stand-Up comics? Give it a rest.

Well... today I started to 'clear the air' with this guy. I got about a sentence into it and realized that he's completely clueless about what he's doing. Has no idea - honestly. Oh... maybe that's environmental, or maybe it's how he's been raised... I don't know. But I decided that there's no reason to has it out with him. None. He's not going to understand it and it'll just seem like I'm picking on him for no reason. After all, he was being "nice" to me.

In these cases, it's time to walk away. Really. He's free to attract as many "friends" as he can with these particular social skills. I only have to work with him. When I see his particular brand of 'humor' in communication, I'll just have to write it off as nonsense, and move on. I'm not interested in being insulted and winked at, as if that makes it all better, and he's not about to change how he deals with "friends".

Why Oh Why Do Some Coders Try to Get Tricky?

February 10th, 2009

python.jpg

I've run into this a lot in at least a few languages - Java and Python. The coder thinks he's saving something by saying:

  import java.util.Date;
  import java.util.Vector;
  import java.util.Stack;

as opposed to simply saying:

  import java.util.*;

I mean really... what are we saving here? Nothing. Exactly nothing. The reading of a file? No... it's still got to read what it reads for the three classes from the one jar file. Microseconds on the compile - maybe. But what have you done? You've forced all additional developers to enumerate all classes they are using. Why? Is it really that important?

It gets worse in Python. I ran into the following code:

  import logging.config, os, sys

where the normal developer would say:

  import logging, os, sys

Can't imagine we've gained anything by just loading the config if we're really do any logging, chances are we're going to actually log. But what I found out today is that this can cause a ton of trouble in systems with the thread package built-in and using the dummy_thread.py stub.

For these guys, you really need to do the following:

  try:
      import thread
  except ImportError:
      import dummy_thread as thread

and in doing this we are able to use the thread package as if it always existed - even when it doesn't. Decent. And the logging package does this - so long as you import it properly. If you try to, oh, I don't know... say import just the logging.config package this isn't done and then all of a sudden the dummy_thread.py isn't pulled into play and you get import errors in the python logging libraries.

Argh!

So I have to ask around and see who might have done this and for what reason. I don't want to make a change that will break something just to get something else to work. We need to have everything working, and if that means we need to put more work into this guy, then so be it, but I'm very clear that this is code written here and not a part of the core Python code.

It's something I'm going to have to deal with on this little project. It's not fun, but it's what I have to do.

Documentation – Why Joe Coder Can’t Write

February 10th, 2009

cubeLifeView.gif

I'm continually amazed at the lack of documentation that most developers I meet write. They don't think it's necessary for their work - after all, they wrote it. Who else needs to understand it? Who else needs to use it? Well... if they need to use it, they'll come and talk to me and I'll walk them through it and then they'll be OK.

It's an incredible double-standard. If they ask for docs from me for something (and most developers I work with have, from time to time) I give it to them. Why? Because I wrote it. I wrote it for myself, and then built the code based on those docs. I know they didn't write the docs otherwise, they'd give them to me.

No, and I've run into a class of developer that if I don't have docs for a process or procedure ready, they want them as opposed to the "talk through". I have to provide it for them so they can make their process or procedure. But when I ask for it, they think I'm being unreasonable. These people are just lazy, no two ways about it.

But the general mass of developers that don't write docs, or even comment their code so that it's at least able to be followed by someone are the ones that get me. They know the value of the docs, but still they refuse to write them. They know it'd make things a lot easier, but they aren't concerned about making the other guy's life easier... they had it hard, so why make it easier on the guy following them? Selfish, is all I can think of. Unkind as well.

So I'm sitting here realizing that I have very little in common with developers like this. I'll continue to work with them, but it's a waste of my time to expect them to change. Maybe they'll run into someone that gets them to write them, and then see the value in having them. But until that day comes there's nothing I can do to make them see the err of their ways. Sad.