Expanding the IRC Interface to Respond to Channel Chats

December 15th, 2010

chat.jpg

Today I was thinking about one of the problems I was having with all these ticker plants and finding the data I needed amongst all of them. It could be a nasty little task to keep them all straight. Certainly, it was going to be a problem for the support crew. And then it hit me - what if I used the channel chats as a "broadcast" mechanism and then the "correct" ticker plant could privately answer me. If there happened to be more than one that had something for me, they would do it privately. Wow... excellent idea! I just had to make sure it was going to work.

The first thing was to realize that the only difference in the IRC message was that the "source" changes from the user (drbob) to the channel (#Hoedown). The source at the start is the same, so we can still pick off the sender, we can now just see that it wasn't a private message, but one to a channel. Sweet.

Now let's see how to put this into our IRC interface easily.

The first thing is to expand the IncomingMessage struct to include the channel. If the message is private, then the channel is empty, and if it's a channel message, it'll be filled in. Simple. Then we can add the lines in the async message reader of the protocol to check the message to see if it's any of the channels we have JOINed, and if so, then slap that into the channel part of the IncomingMessage and have it "handled" on another thread.

In the handler we just have to see if there's a channel defined in the message, and if so, we can then call onChannelMessage() otherwise we'll call the old onMessage() for the private messages. The reasoning here was just to make it clear what kind of messages you are responding to. It doesn't have to be like this, but to me, it makes it very clear what you expect, and if you don't want to mess with channel messages, then simply don't implement the onChannelMessage() method and it'll be fine.

All this coding took me all of about 30 mins, and then I started testing it with a simple command - who has AAPL?

Sweet. Worked like a champ.

Then it was a simple process of migrating a few of the private chat messages to the "public" messages with private replies. Instead of errors, I just had it return nothing. That way, if the ticker plant doesn't have anything useful to add, it's simply silent. This makes a lot of sense for these types of chats.

In the end, I have a simple way to ask the System as a whole a question and have a private response from the one guy that can answer my question. I love this interaction. Very nice.

Favorite C and Obj-C Features of the Week

December 15th, 2010

xcode.jpg

I'm not sure if I'll do a lot of this, but today I was working and realized that there's something I've been using in C/C++ that I really love. I also was thinking about something in C/C++ that I don't love, and how Objective-C does is so much better. So I decided to have a Feature of the Week - for at least this week.

C/C++: Assignments Everywhere

I didn't used to do it, but of late, it's made my code so much more readable to me. Maybe it's me, maybe I've gotten to be a better coder, but I used to write a lot of code that looked like this:

  variant   *a = getVariant(3);
  if (a == NULL) {
    cLog.error("unable to get variant #3");
  }
  a = getVariant(2);
  if (a == NULL) {
    cLog.error("unable to get variant #2");
  }

and it's even worse in a re-used iterator:

  std::vector<std::string&gt::iterator   it = mClients.find("Steve");
  if (it != mClient.end()) {
    // do something with the fact we have 'Steve'
  }
  it = mClients.find("Jeff");
  if (it != mClient.end()) {
    // do something with the fact we have 'Jeff'
  }

But it doesn't have to be this way. With the C/C++/ObjC ability to have assignments anywhere, you can compress this all very nicely:

  variant   *a = NULL;
  if ((a = getVariant(3)) == NULL) {
    cLog.error("unable to get variant #3");
  }
  if ((a = getVariant(2)) == NULL) {
    cLog.error("unable to get variant #2");
  }

and the re-used iterator becomes:

  std::vector<std::string>::iterator   it;
  if ((it = mClients.find("Steve")) != mClient.end()) {
    // do something with the fact we have 'Steve'
  }
  if ((it = mClients.find("Jeff")) != mClient.end()) {
    // do something with the fact we have 'Jeff'
  }

Sure, this isn't rocket science, but it's allowed my code a new level of readablility - certainly in the looping where the definition of the variable is outside the loop and the assignment is within it. There's nothing like readable code. It's a real benefit.

ObjC: The Clever Mr. nil

But one thing I love about ObjC is it's use of the nil. It's far more than the C/C++ NULL because you can message nil with anything, and that's where it's so valuable for code readability. Take the following code, for instance. It's going to get a few things in a data structure, and to do it right, and by "right" I mean safely so as not to get null pointer seg faults, we need to do something like this:

  TPClient   *boss = getBoss();
  if (boss != NULL) {
    Channel  *chan = boss->getChannel("red");
    if (chan != NULL) {
      cLog.info("red channel has %d bits", chan->getBits());
    }
  }

Sure... you can be careless, and write this all optimistically as:

  cLog.info("red channel has %d bits", getBoss()->getChannel("red")->getBits());

but if there's any problem in those calls, it's a SegFault to be sure. But ObjC and nil can handle this nicely:

  [NSLog @"red channel has %d bits", [[[self getBoss] getChannel: @"red"] getBits]];

and the latter is so much more readable. It's the fact that you have to code defensively that kills the readability of the code. Not so in ObjC. It handles the possibility of any one of these steps returning a nil, and carries on as if that's expected behavior.

There you have it. My favorite little language do-dads for today.

Christmas Shopping

December 14th, 2010

Christmas Tree

Today I'm off to do as much Christmas Shopping with Liza as we can get done in a day. We need to get the kids a few things, and while they are selected in our minds, they aren't physically sitting in the house, so it's necessary to go and get them.

Ho ho ho...

In all honesty, I don't mind the shopping. Liza's a lot of fun to be around and we laugh and giggle about all kinds of things - from the silly gift ideas to the people in the lines, and even the cars in the parking lot. It's a lot of fun.

Tough Afternoon – Glad I Pushed Through it

December 13th, 2010

Dorey.jpg

This afternoon I wound it exceptionally hard to get motivated. I mean really, really hard. I just wanted to do something a little interesting, but that was not in the cards. I didn't have anything pressing I needed to get done, and I was still waiting for management to make some announcements they had talked about, so I was really just in the "Just keep swimming" mode.

I had things that needed to be done - there's always things that need to be done. So I got a few of them out of the way. I need to make a parser for the ticker plant responder to change values, and I really couldn't get geared up for that this afternoon. It's going to be tough, and I need to be fresh when I start on that.

So I did the grunt work that needed to be done. Script updating... made a few shell apps for some things I'll need in the coming weeks... standard, but uninspired, stuff.

But if there's one thing I've learned over and over again... it's that the individual that pushes through these tough parts and continues to create, has an incredible advantage over the one that requires motivation. Pushing through the tough parts is a skill. It needs practice, and this afternoon my "muscles" are "sore" from the "workout".

Solid New IRC Features Deployed

December 13th, 2010

chat.jpg

This morning I finished up a lot of work I had started Friday afternoon about getting some useful features into the IRC interface for my ticker plants. I wanted to be able to get people something more than a proof-of-concept, but it was taking more time than I'd expected. I wanted to make it possible for any number of users to get the sampled stats I log to the Log4Cpp file. That meant I needed to modify the ticker plant itself to have a list of "interested parties" and then run through that sending the stats.

None of it was all that hard, but getting it all together in the responder and the ticker plant was just more time than I had to give on Friday evening. After I got that all working, I wanted to add a few more things: querying an instrument for it's messages... querying a family of instruments for their messages... restricting these to a certain message type... all things that I know the support guys are going to want to do.

I have to say that I'm pretty pleased with how all this is turning out. It's very easy to add these features into the responder and into the ticker plant. But then again, I've done this a few times, and I know the problems I faced in those previous incarnations, and what really worked well. This time I only had to do the "good" stuff, and it worked wonderfully.

I'm not nearly done, but I wanted to get these all in and pushed up to the development environment where people can play with them. That will get them thinking about what I can deliver for them, and since almost all this is for the support folks, I wanted to get them thinking about this as soon as possible.

Good morning.

Google Chrome dev 9.0.597.16 is Out – Fixed

December 13th, 2010

GoogleChrome.jpg

This morning I noticed that Google Chrome dev 9.0.597.16 was out with the fix for the botched release they had last week. Basically, you could scroll down with the mouse wheel (or two-finger swipe on the Mac), but you couldn't scroll up. Kind of frustrating to go one way and not the other.

But true to their word, they released a new version with the fix for the scrolling in just a few days. For that, I'm grateful. I hope they have this in their test suite now for subsequent releases.

More Issues with IRC Servers

December 10th, 2010

chat.jpg

This morning I've done a bit of coding as well as waiting on the IRC server. The admins have decided to switch to InspIRCd as it has user-logging which is going to be critical for compliance purposes - and The Shop always has to be aware of that. So that's a significant change.

The biggest issue I've seen so far is that the response from InspIRCd is a lot more like the RFC for IRC. It's got the numeric codes in the responses that can be used to determine what is the nature of the message. I was missing that in the previous server, and I'm glad it's back.

Still... I need to get a stable server up and then I can start to test my changes.

Google Chrome dev 9.0.597.15 is Out – And Broken!

December 10th, 2010

Well, this is a first for me... Google Chrome dev 9.0.597.15 is out and it's broken. Specifically, I can scroll down with the two-finger swipe, but I cannot scroll up. The release notes even say that this is a problem, and that a fix should be released in short order.

Hmmm... I can see a lot of things missing the testing, but scrolling? Really?

Messing with IRC Servers and Stuff

December 9th, 2010

chat.jpg

Well... it's been an interesting day. Earlier in the day I got word that there is now a nice, new, IRC server based on ircd-ratbox 3.0.6 running in The Shop. I was free to test my IRC client work and then integrate it into my ticker plants. The testing was pretty fun - I had a logic flaw because I wasn't starting the Protocol thread for doing the async reading from the socket. That was an easy fix - add a simple check and start() to the addToResponders() method. If I don't have any responders, there's no need to read anything.

The next one was trimming the whitespace off the incoming messages. Again, pretty easy, but it was annoying to see it. After that, it was tested and ready to go. Sweet.

I then uncommented the code in the ticker plant and then started firing up the ticker plants.

Massive problem! The IRC server was only allowing two of my ticker plants, in addition to my one xchat client on my box. Clearly, this is a configuration issue, and the rest of the day has been spent working with the admins trying to figure out what the right parameter needs to be in order to get things to work.

No joke... it's been a long while. But to be fair, it's not trivial. I remember spending the better part of a day getting the configuration right back when I set one up for something just like this. It's a mess of config values in the files - all because they are designed to protect against bad clients and bad people on good clients.

The problem I'm seeing in my code is that something happens and it causes my ticker plant to consume enormous amounts of memory (15GB) and race a CPU - not good. So I need to figure out how to handle the boost asio better to make sure that no matter what the IRC server does, I'm not getting into that situation.

That's tomorrow.

Upgraded to WordPress 3.0.3 at HostMonster

December 9th, 2010

I saw this morning that WordPress 3.0.3 was out with security fixes:

This release fixes issues in the remote publishing interface, which under certain circumstances allowed Author- and Contributor-level users to improperly edit, publish, or delete posts.

Sounds kind of ominous. Gee. So I went to HostMonster and upgraded my installs.

Done. Whew.