It’s Always Fun to be Surprised with a Three-Day Weekend

January 18th, 2008

cubeLifeView.gif

I'll admit that I'm about as clueless of my surroundings as one grown-up individual can be, but today had to be right up there with the best of them. I was working late today working on the efficiency of my historical cache in my market data server and went to the bathroom before leaving. I ran into a friend there who happened to say "Have a nice extended weekend."

What?

I asked him, disbelieving what he was telling me, and sure enough. Monday is a UBS Holiday - no work. I was floored.

Of course I had to ask a few others, because you never know when people are trying to pull a fast one on you, but the information checked out. I have Monday off.

Had I left on time I would have come in on Monday and been all alone.

Well... almost. When I told one of my co-workers he was floored too. He didn't know either. We both had to laugh. But then we realized that this is exactly the way we like it. Don't tell us too far ahead... then it's not a fun surprise. Now, I feel like I really have something to be happy about. Like Christmas all over again.

What a sweet surprise!

Building an Embedded Crontab System

January 18th, 2008

cplusplus.jpg

Today I was working on my latest new application for price feeding. Part of this app is a crontab-like system. I've put several into several apps I've built in recent years, but most of them have been database-driven primarily because I thought it would be easier to use, and I could get something far better than the conventional crontab system from Unix. I was wrong.

Oh, the database-driven crontab system works fine, but it requires a database connection to work, which has it's pros and cons. The pros are obviously that it can easily be global, easily modified, thread-safe, and secure. You can write any tools you want to edit it, and it can be as complex or as simple as you want.

The cons are that unless you really take the time to write the tool, using SQL to modify the jobs is a real pain in the neck. My problem has been that I change the database crontabs so infrequently that building a tool has never really been necessary.

So this time, with this price feeder, I decided that a file-based crontab was going to be easier to use, easier to understand, and just as flexible. Face it... it's a bunch of fields where the first five are the when and the sixth is the what. So today I built a nice little crontab system that easily fits into applications.

The format of the crontab file is the same as unix crontabs, so it's easy for people to know what to expect when they look at it. The thread that runs in the app that checks for differences is simple - simply using stat() to get the last modification time, and checking to see if it's after the last known modification time of the file. If it's been updated, then we drop all the loaded jobs, reload and reparse the crontab into a series of jobs, and then check what jobs need to be done this minute.

I keep the time of the last minute we ran, sleep for 2 sec between checks, so we're going to be firing off the at-the-minute-jobs pretty darn close to the top of the minute. Also, we're not going to be firing off the same job more than once in the target minute. Pretty simple.

The most interesting thing was the parsing of the time field codes. Crontab allows three basic styles that can be put together with commas, separated by any whitespace:

  • n - a single entry. For all fields it can be numeric, and for the months and days of the week field it can be the names.
  • n-m - a range, inclusive of the endpoints. Again, for all fields it can be numeric and for the month and day of the week it can be the names.
  • */i - every i units. This requires the i be numeric on all fields and will indicate valid times every i units. Therefore, */5 in the minutes column means every 5 minutes.

It was really surprisingly fun to have each of these cases handled nicely in the code. The logic was pretty simple - parse these fields into lists of applicable values and then put them into lists. When checking a time, simply break the actual time into the necessary components and see if each component fits into the approved values for that field for that job. If all match, then the job should be executed. If one misses, then skip it and go to the next.

With the caching of the cronjobs, we're not doing more reading and parsing than we need to. This makes the system less consuming of resources, which is always good. The command portion of the job can be anything we want - complex or simple, it's just up to what I need the app to be able to do.

When I get this app all done and everything is working, I'll probably pull this out and put it into CKit as a more reusable component. I just want to make sure that it's got all the features I need before I put it in CKit.

Adium 1.2 Has a Sound Bug

January 18th, 2008

Adium.jpg

This is the second time this has happened to me - maybe more, I'm only starting to notice it today. I'm running Adium 1.2 on my MacBook Pro with 10.5.1 (fully updated) and when I put my laptop to sleep I think it turns off the sound on Adium until I restart the app. I'm going to check the website to see if they have any bugs reported on this - I know the last update included a new QuickTime - maybe that's to blame.

I just know that I don't like not being able to hear the chat announcements. I count on them to get my attention when I'm working at another machine. Crud.

UPDATE: I put in a trouble ticket for this bug. We'll see what they have to say when someone gets a chance to look at it.

[1/22/08] UPDATE: Adium 1.2.1 is out and it fixes this bug nicely. Don't know if it's something else, or my post, but I'm guessing that it was already in the works.

Chasing Down Wild Bugs

January 17th, 2008

bug.gif

Last night I got a call from Hong Kong about slow ticks in the server. I talked to the support guy there for about 30 mins to get this out of him, but in the end, I figured out that it was a ticking issue, and further discussions with this guy were going to be pointless and frustrating. So I got online and checked things out.

Turns out there were a few things that weren't right, but nothing pointing to the real problem - which was that the ticks were seemingly working, but not as fast as they should and not as regularly as the ought to. I looked at a few of the logs and one of the instruments had no position on it, but positions on it's options, and so should have been in the 'positioned' poller queue - as opposed to the 'non-positioned' poller queue. I put in a fake position on the instrument and it moved to the right queue, but didn't start ticking like it should have.

I told the support guy over chat to simply hand mark these guys for the night, and I'd get to the issue in the morning and send an email about what I found. I needed to get some sleep or I wouldn't be able to really find the solution to the problem in the morning.

What I found was most interesting. Three problems in two systems caused this issue. The first one was a fix I had put in for the price feeder yesterday for augmenting the trade date/time with the current date/time when no trade date/time was sent by the exchange. The problem with the implementation was that it was also allowing ticks with no trade information to update the trade date/time. This meant that quotes were updating the trade date/time and that's no good. Not at night in Chicago when the ticks are for the next business day in Hong Kong. I was 'stomping' on the trade date/time and move it back a day. Bad move.

This meant that the server was looking at these prices and saying "Hey, this is old data... I need data for 'tomorrow' now." and throwing the ticks away. This explained the hit-n-miss ticks - some came in on the right date, and then the date was overwritten with the quote and no more ticks. Unfortunate, but that meant that I really needed to fix two things - the price feeder and the interpretation of 'today' for ticks.

Fixing the price feeder wasn't bad - I simply made sure that there was some evidence of a trade before defaulting to the current date/time for the trade time. This will make things much more reasonable. At the same time, I checked to see if the current date/time was before the trade date/time existing on the price. If so, then I didn't overwrite it as that would be moving it back in time.

The problem in the server was that I needed to have some knowledge of the region of the instrument. Specifically, I needed to know if it was an Asian instrument. For if it were, the checks on the date of the tick needed to be relaxed by the time difference. So I got a list of all the Asian currencies, made that a configurable option on the server, and then checked each instrument to see if it's currency was an Asian currency. If so, then I relaxed the time check to be after the start of the server so that we would not be in a position to throw away ticks when I knew they were really good - just in the wrong time zone.

The final problem was a simple fix to make sure that when I looked at an instrument to see if it needed to be in the fast tick pool or the slow tick pool, I used the method on the base instrument that checked to see if there were any positions on the instrument or on any of it's children. This fixes up the mistake of improper classification in the first place.

One nasty problem with three important changes. Not a bad morning.

Working with plists in C++/CKit

January 16th, 2008

CKit.jpg

While I know there are a ton of linux libraries that deal with plists, I needed to have my 'data tree' class in CKit read and write them. It's not going to be 100% plists, but it's awfully close, and for all the times I'm going to need it, it's going to work perfectly.

I've been spending the last two days hammering on this and I have to admit that it's making my head hurt. It's a ton of work with the variants, and that means a lot of if/then/else work for each data type the variant can hold. Nothing really romantic about it, just practical code that's going to make it a lot easier for me to have nice, useful application preferences from here on out.

The nicest thing about it, I suppose, is that I retain the use of the serialization codings for the variant data type. This means that should I want to store a table in the plist, it's possible without it being a total mess. Yes, it's going to require that the person editing it is going to have to know what they are doing, but that's not a horrible thing, either. I'm hoping that this is going to be a nice base to work off of in the future.

It’s scary when you know the product better than the vendor

January 16th, 2008

cubeLifeView.gif

Here's something that happened to me today that makes me a little scared of the vendor relationship I have with our price feeder. First, it's another group in the Bank, so it's not like they are a real vendor - and for that I'm eternally grateful. But even so, today I saw a problem in the feed and I was able to figure it out faster than they were. More to the point, when I explained it to them, they had to take a step back and think about it before they realized what the problem was.

It's all about trying to be clever and efficient - which normally, I'd be in support of, except where it causes problems for others. Get it right then get it fast. That's the way to do it. Unfortunately, they have it right, but using it then becomes very difficult as what they send (only the diffs from the last tick) isn't really enough to do the job of interpreting the data.

There are two fields of importance in this example: the price and the time it was sent from the exchange. Let's say they aren't properly mapping out the time from the Reuters FIDs, and so all I get is a date - no time. When a new tick comes in, the date hasn't changed and the time hasn't been mapped, so the date/time hasn't changed from it's last value, and so it's not sent. The price is, but without the time, when was this price issued? Today? Is it current at all?

Had they sent the date/time every time then this would not be an issue - but they can't do that - inefficient. So because they want to only send the diffs we have to put in a lot of extra logic to figure out what it was they meant to send.

It only gets more complex when you think that a "tick" may come form the exchange with a date/time of 'today' and a price of 0.0 - meaning it's not really a tick. So I properly ignore that. But if the date/time is never resent, then all subsequent ticks don't have an 'old' date/time to run with. As I said... it's problematic.

But it's the fact that this doesn't seem to represent a problem to them that bothers me. You should be in the mode of helping your customers, not making it harder for them. In this case, they were definitely making it harder by not being a little less efficient and sending the date/time again. Sigh...

MacWorld Keynote

January 15th, 2008

Apple-logo.jpg

It's not that every keynote needs to have something for me. I didn't really expect anything from this one - based on the rumor sites, and I wasn't surprised. I like the Time Capsule, and I think the MacBook Air has an audience (it's not me, but it's got an audience), and while I like the option of movie rentals, I have that in Comcast OnDemand, so there's nothing new there.

The addition of the apps to the iPhone and iPod Touch are nice, but since I don't have either, I'm not impacted by the announcement. I was a little taken aback by the $20 fee for the iPod Touch users, but I guess they have to sell it for something - like the 802.11n update for Tiger. I did think that $20 is steep, but what the heck... it's the cost of early adoption.

I will say that the only thing that looks even remotely like something I might get is the Time Capsule. The problem there is that the drive is contained in the box. It'd be great to be able to configure the unit to use a network drive - or let Time Machine use a network drive itself, so that I wasn't stuck with their drives.

I want to put in a RAID 5 system with lots of expansion, and that's not in the cards at this time with this solution. Well... maybe soon enough, they'll have some update for this to Time Machine. Until then, I don't really mind the cord all that much. It's an inexpensive solution to a hard problem that I really like having with me.

Making a tarball of CVS Changes

January 15th, 2008

Apple-logo.jpg

One of the things I like to do when I've made changes to several files in a CVS directory - and haven't yet checked them in, is to make a tarball (a .tgz file) of them so that I can move them to another machine for testing. For example, working on cross-platform code, it's nice to get it working on one platform and then move it to the next and verify it before checking it in. This way all the changes for the modification are in the one CVS check-in.

I wanted to make a simple alias for TCSH that did this on my Mac. I was doing it all the time and it just seemed smart to finally do this right once and then just use it from here on out. The problem I got into were these "Apple Dot" files (._file) that tar was including in the tarball even though they weren't listed in the list of files to include - nor could I exclude them with the command options.

So I did some googling and found the COPYFILE_DISABLE environment setting in Leopard. If this is set to 'true', then these Apple Dot files will not be copied. But, since I didn't want to make a big change to all my shells, I decided to simply make it defined for the one command.

Finally, then, here is the alias:

  alias tcu 'setenv COPYFILE_DISABLE true; tar zcvf \!* `cvs -q update |
      grep -v \^\? | sed -e "s/^[AM] //g"`; unsetenv COPYFILE_DISABLE'

(it's all one line, of course)

Bank of America Buys Countrywide

January 14th, 2008

pirate.jpg

OK, I'm not one to care a lot about business moves because the real reasons for them are most often than not inaccessible to the public. Oh, there's a public spin on the deal, but the real underlying reasons are often much less noble, and are far more focused on the profit a few can make on the deal.

However, today's announcement that Bank of America (my personal Bank) buying Countrywide (the holder of my mortgage) has me both interested and a little upset at the sub-prime lenders. I'm a "30 year fixed" person, myself. Yes, it means that I could possibly get more house with less per month if I did some more creative financing, but that's not the purpose of a mortgage, in my opinion. I need a roof over my family's head. I need stability for them. I don't need to play a game with my kid's home. I need to be reasonable, and safe.

So the idea of sub-prime mortgages is just something that may get some people into homes they could not afford otherwise, but in the end, I'm not sure that they can stay in those homes. Face it... if you can't afford the mortgage, then what makes you think you can afford the house? Taxes always go up... fees... assessments... all those costs with a home always rise. So if you can't afford the house to day on even a standard ARM, why get in at a sub-prime level? You're not going to be able to keep the place unless you start to make a lot more money - but at that time you're refinancing the mortgage and you're not sub-prime anymore.

So when I see this I get a little angry. Countrywide is in trouble, and while they aren't going to foreclose on me, they might have to sell assets to stay above water. But then my bank comes in and buys it up, so I'm bailing out myself. I sure hope it works out for me. In the end, it's stability that the markets want, and this offers some, which is good. But wow... I didn't see it coming.

What are you going to do today that’s worthy of me?

January 11th, 2008

product-15in.jpg

I was watching this TED talk by J.J. Abrams entitled The mystery box, and he was talking about the unlimited possibilities of a blank page, and his love affair with Apple computers. He pointed to his Powerbook and said:

This machine is great. It's like it's looking at me and saying What are you going to do today that's worthy of me?

I share that feeling completely. I've had the 17" Powerbook since it was first created. Now I have a 17" MacBook Pro, and I think I'll always have the best laptop Apple makes. It's just a feeling of the quality of the hardware and the software. The feeling that there's just about nothing I can't do on this guy. It's the creative palette that really does allow you to achieve your best. And in that, it's expecting you to give it your very best efforts as well.

And there are certainly more days than I can remember looking at the screen of this machine and feel it look back at me with the same feeling: what are you going to do today, Bob, that's as good as this? I've listened to Steve's keynotes and they are of that same tone - these are the machines of the dreamers... the creative professionals that will shape thought... change the world. What are you doing that's like that? I just love it to pieces.