MarsEdit 3.3.5 is Out

October 26th, 2011

MarsEdit 3

Daniel released MarsEdit 3.3.5 with some nice support for right-to-left languages. Pretty nice internationalization, actually. I'm not sure I'm interested in doing that level of work, but I'm sure glad someone is. MarsEdit is a wonderful program and I use it every day that I'm not overloaded. It's something that's really enabled high quality postings on my journal. Very nice work.

Google Chrome dev 16.0.912.12 is Out

October 26th, 2011

Google Chrome

This morning Google Chrome dev 16.0.912.12 was released and I picked it up. When I went to the release notes site, I saw that Google Chrome 15.0.874.102 was released to stable which just blows me away. That means that stable and beta are both 15.x.x.x and dev is on 16.x.x.x - that's not going to stay that way for long. I'm guessing dev is jumping to 17.x.x.x pretty soon. Additionally, there were no release notes for 16.0.912.12 at the time the code was available. So maybe it's coming sooner than later.

Always interesting times.

[10/28] UPDATE: don't blink - they just released 16.0.912.15 with typically sparse release notes. That's less than a day after the last release. Yup… it's about to jump to 17.* soon…

Creating a Solid, Reliable C++ Wrapper for hiredis Library

October 25th, 2011

Redis Database

Most of today has been spent trying to get my simple C++ wrapper around the hiredis C library for redis working in a way that allows for a significantly more robust usage pattern than I originally had. Specifically, all was fine until I shut off the redis server, and then my client would try to recover and reconnect and end up dumping core. The problems are only made worse by the fact that I really had no support docs on the hiredis site - only the source code, which is optimistic in the extreme. No argument checks, etc. make it ripe for a problem if it's not used exactly right.

Clearly, I wasn't using it exactly right, and those misusage patterns were what was causing the code dumps. So the first thing was to track down what I was doing wrong, and that meant that I really needed to become much more familiar with the hiredis source code. To be fair, it's a decent open source library, but it's missing so much that would have added so little to the runtime load and would have made it far more robust to the kinds of misusage patterns I had in place. After all, my code worked, so it's not that it was totally wrong, it's just that when things started to go badly, the things that you needed to do become far more important than when things are going well.

For example, if I wanted to send multiple commands to the redis server at once, you can run several redisAppendCommand() calls, but each really needs to be checked for it's return value. This isn't clear in the code, but it's very important in the actual system. Then there's the calls to redisGetReply() - typically one for each call to redisAppendCommand() - but not always. Again, you need to check for the critical REDIS_ERR_IO error that indicates that the redis context (connection object) is now so far gone that it has to be abandoned.

Then there's the reconnection logic. It's not horrible, but you have to be careful that you don't pass in any NULLs. There simply is no checking on the hiredis code to ensure that NULL arguments are skipped. It's simple to do, but it's not there - not at all.

In the end, I got something working, but it was hours of code dissection and gdb work to figure out what was going wrong and what needed to be done to handle the disconnected server and then the proper reconnection. Not fun, and several times I was wondering if it just wouldn't be easier to write my own as it's all TCP/telnet based anyway… but I kept going and in the end I have something that's reliable and solid. But it was nasty to get here.

Rounding Can Really Be a Pain in the Rump

October 25th, 2011

bug.gif

This morning I had a funny little bug in the Greek Engine that was really a hold-over from my Ticker Plants, regarding the creation of the security ID - the 128-bit version of the complete instrument description for use in maps, keys, etc. The problem was that the exchange codecs were correct in their work, it was the creation of the security ID that was at fault, and I needed to dig there to find the solution.

Basically, I pack the components of the instrument definition into a 128-bit unsigned integer, and to so this efficiently, I need to have a pointer that points to where the next component needs to be "dropped in". When I got to the strike, which was passed in as a double, I had the code:

  // finally, slam down the strike
  *((uint32_t *)ptr) = htonl((uint32_t)(aStrike * 1000));
  // swap the network order bytes to host order
  byteSwap();

and because of the (aStrike * 1000), I was getting 64.099 when I should have been getting 64.10, among other rounding errors. What I needed to do was pretty simple, but essential to get the right answer:

  // finally, slam down the strike
  *((uint32_t *)ptr) = htonl((uint32_t)(aStrike * 1000.0 + 0.5));
  // swap the network order bytes to host order
  byteSwap();

and with that, we got the right numbers. We even got the right thousandths place in the case of 8.125, for example. I'm sure there was partly the need to cast the 1000 into a double, but the additional movement by a half was the thing that brought it home.

Now we're OK.

Dropping Join/Part Messages from Colloquy and Adium

October 24th, 2011

Colloquy.jpg

One of the things that I haven't liked about Colloquy and Adium is that for the sake of accuracy, they have all the join/part and connect/disconnect messages. The problem is that on busy IRC channels, or even some days when my friends on Adium are in and out, those messages are the vast majority of the messages I see in the window. That's not the ideal situation for me, so I was looking for a way to clean those messages out.

Unfortunately, there is no option on either app to remove these messages. Luckily, I found this in a conversation in the Colloquy chat room. It's how to change the CSS for the join/part messages so that they don't show. Neat idea! You just have to Option-Click on the Apperance button in Preferences and it'll pull it up in an editor, and you can add:

  .event {
    display: none;
  }

and then a quick /reload style in Colloquy and the join/part messages are gone!

Adium.jpg

With this, I decided that it might be worth trying it on Adium as well. After all, I know from my own hacking on the Adium themes that they are CSS and HTML driven as well. In Adium, you need to get to the theme in question and then add:

  .status {
    display: none;
  }

to that file, and restart Adium and you're done!

These two changes are great! They allow me to keep more of the conversation in the window without scrolling. What a wonderful change!

Getting C++ Constructors Right is Vitally Important

October 24th, 2011

bug.gif

I ran into a problem that completely reinforces my belief that coding standards are a very good thing. And I was the culprit here - but only because I missed it, not by choice. What I had was a constructor for a Dividends set - basically dates and values in a table that needs to be treated as a single unit. The copy constructor for the instance looked like this:

  Dividends::Dividends( const Dividends & anOther )
  {
    // let the '=' operator do all the heavy lifting
    this->operator=((Dividends &)anOther);
  }

and the operator=() method looked like this:

  Dividends & Dividends::operator=( Dividends & anOther )
  {
    if (this != & anOther) {
      boost::detail::spinlock::scoped_lock   lock(mDivsMutex);
      mSetName = anOther.mSetName;
      mSecurityKey = anOther.mSecurityKey;
      mDivs = anOther.mDivs;
      mUpdateTimestamp = anOther.mUpdateTimestamp;
    }
    return *this;
  }

Now the trick here is to realize that the Boost spin lock is really just an atomic integer that they wrap with CAS operations. It's good, but it really needs to be initialized properly or it's not going to function well. What I'm doing in the copy constructor isn't wrong in the sense that it's logic is wrong, but the implementation is horrible.

When I saw this, it was clear to me what the bug was: the spin lock wasn't initialized properly, and the use of it in the operator=() method was locking the thread. Bad news. The solution was simple:

  Dividends::Dividends( const Dividends & anOther ) :
      mSetName(anOther.mSetName),
      mSecurityKey(anOther.mSecurityKey),
      mDivs(anOther.mDivs),
      mDivsMutex(),
      mUpdateTimestamp(anOther.mUpdateTimestamp)
  {
    // the initialized values do everything I need
  }

and the advantages are clear: since we're constructing a new instance, locking the new instance isn't necessary - no one knows it's there. Also, we properly initialize the mutex, and that's everything in this problem.

Standards. Get them. Live with them.

Breaking Out Fundamental Data for Greek Engine

October 24th, 2011

High-Tech Greek Engine

This morning we realized that some of the fundamental data we are using in the Greek Engine is not fixed for each security, but in fact, is dependent on the prime broker for that trade. This means that we needed to take that piece of data out of the security definitions table, and make it a separate data table, with set names, and all that noise, so that we could define the right rate in the profiles.

It's a complicated way of saying we took what we believed to be a dependent variable in the Greek Engine and made it independent. The upshot of that is that we needed to be able to handle data source updates as well, and that means threading this new independent variable's updating scheme through out the code. Not horrible, but it takes time to do it right and update all the classes where the control logic needs to flow.

In the end, I wanted to get this done before lunch, and I just made it. Nicely done, as the last time I did this it took me all day.

Finally Figured Out Nasty TBB/Uninitialized/Locking Bug

October 21st, 2011

bug.gif

Today my co-worker and I finally figured out the last, nasty bug in the Greek Engine that I've been working on for quite a while, and it's brought to a close a stage in my life that brings with it a lot more questions than answers. I've been working on this project for about six months, and while that's not very long for a project of this type, it's a long time to be getting a lot of grief from upper management about the time this project is taking, and the fact that it's not already in production.

I'm no idiot, I know that the finance industry is focused on What have you done for me today?, but when I'm asked to build something like this Greek Engine, and it's clear that it's not a four week project, then it's tough to sit here and take the accusations of incompetence and neglect when what I'm building is for the benefit of the name callers. I'm thrown back to the Little Red Hen: Who will help me back the bread?

In the end, it doesn't really matter because I did this for me, and not for them. I choose to not deliver crap, and they are the hapless beneficiaries of my morality. It's not something I'm necessarily proud of, but it's what I've come to see as the way things often are. I make a choice, and for the most part, there are detractors, and many of those detractors are in fact beneficiaries of my work. I do the work under their critical and harassing eye, word, and act, and in the end, they are the ultimate winners in this game.

Which, of course, isn't true at all, is it? They don't really win, because they don't have the ability to do what I've done, and they probably don't even have the ability to maintain the work I've started. But they benefit because they get to use the software I've written, and as long as I'm willing to allow them to play their sad, little role, they believe themselves to be my master.

But they aren't.

And it's not even close.

But today I've finished the last major problem on this project. It's now going to be a bunch of little features that are pretty easy to put in the code. Nothing major, and there's no real performance issues to deal with. It's pretty much done. I can sit back and look at the work I've done and smile. It's amazing work, really. I never thought it'd come together in six months, but it has. That's an impressive delivery schedule in my book.

And that's the only one that matters.

Google Chrome dev 16.0.912.4 is Out

October 21st, 2011

This morning I saw that Google Chrome dev 16.0.912.4 was out, and includes the new V8 engine 3.6.6.5 as well as quite a few nice Mac improvements including OpenGL. It's getting faster on the redraw, that's for sure, so I'm happy about that. Keep them coming, guys!

Finally Found Colloquy Developers on FreeNode

October 20th, 2011

Colloquy.jpg

Today I finally found the Colloquy developers on FreeNode (IRC) because I wanted to start working on getting the latest Growl 1.3 working with Colloquy. I've spent a little of the last several days looking at the other Mac OS X IRC clients, and while there are a few that look OK, there's nothing that's as well-targeted for my needs as Colloquy. I looked at Textual IRC Client, and while it was reasonably minimal, it didn't have the configurability in the themes to make it really what I wanted. Basically, I want a small but readable IRC window that I can have up all the time to monitor all the development group chats that I monitor as part of what I consider to be "important to my life in the trenches". So if I can't change the font, or vertical spacing, it's possible that the client isn't going to be something I'm really interested in.

Thankfully, Textual IRC Client is available as a trial download, so I was able to try it without having to buy it on the Mac App Store. The same goes for the other one I seriously looked at - Linkinus. I have to say that this was a little closer to my liking, but again, there's no way for me to make a theme for it, and if that were the case, I'd have bought it.

It's got all I need - and to be fair, Textual IRC Client had most of what I needed, but in both, it's the visual representation that fell short. Neither seemed to have the ability to configure the theme to the level I wanted to get a view that would fit into what I had with Colloquy.

Growl 1.3

After all, the only real problem with Colloquy is the Growl 1.3 integration. Also, it seems that the updates for Colloquy have been few and far between, and with Lion, there are a lot of new features that probably need to be addressed. But on the whole, it's not a lot of changes.

So I set out to find the developers of Colloquy and see if I could get the code and work in the Growl 1.3 support. What I found was that Colloquy (#colloquy) and Growl (#growl) are on FreeNode, and that one of the Colloquy developers has already integrated the Growl 1.3 beta Framework, and he's just waiting for the Framework to be released. Wow. Sweet deal! This really help, as all I have to do is watch the chats for the release of the Growl 1.3 Framework and then the Colloquy guys will drop a new version, and I'll have everything I need.

Great news. Can't wait for the new releases.