Archive for the ‘Open Source Software’ Category

Adium 1.4.3b1 is Out

Monday, June 27th, 2011

Adium.jpg

This morning I got a tweet from the Adium developers that 1.4.2b1 was out with some of the "lost" MSN features restored. It's not a surprise, with 1.4.2 taking a few away, it's not at all surprising to see them respond quickly with a new release. I was a little surprised that they added in the Facebook connectivity, and with a web page authentication. Interesting, but a little odd. I'm glad I'm not a big Facebook fan. Kinda creepy the way these guys are requiring web page-based authentication.

Anyway, it's running fine, looks OK, and glad they are on top of these updates.

Wild Bug in Date Conversion Code

Thursday, June 23rd, 2011

bug.gif

We came across a very wild bug today with date conversions. Basically, the problem is taking an option's expiration in the form YYYYMMDD and seeing if that date falls on a weekend. If it does, then back it off to the Friday before the weekend. The original code I had made use of mktime()'s ability to compute the "day of the week" given the year, month and date:

  struct tm  when;
  // will this struct up with the date as we know it
  when.tm_year = aDate/10000;
  when.tm_mon = (aDate - (when.tm_year*10000))/100;
  when.tm_day = (aDate - (when.tm_year*10000) - (when.tm_mon*/100);
  // correct the values for the call to mktime()
  when.tm_year -= 1900;
  when.tm_mon -= 1;
  // now call mktime() and let it fill in when.tm_wday...
  mktime(&when);
  if (when.tm_wday == 0) {
    // it's a Sunday!
  }

what we were seeing was that the day of the week was all wrong. In fact, the year, month and date coming back from mktime() were being randomly scrambled. Very odd.

The solution was simple - zero out the struct before using it. Sounds simple. But you'd think the compiler would do this for you. Nope. it's uninitialized memory. Silly me.

The fix looks remarkably similar - save one line:

  struct tm  when;
  bzero(&when, sizeof(when));
  // will this struct up with the date as we know it
  when.tm_year = aDate/10000;
  when.tm_mon = (aDate - (when.tm_year*10000))/100;
  when.tm_day = (aDate - (when.tm_year*10000) - (when.tm_mon*/100);
  // correct the values for the call to mktime()
  when.tm_year -= 1900;
  when.tm_mon -= 1;
  // now call mktime() and let it fill in when.tm_wday...
  mktime(&when);
  if (when.tm_wday == 0) {
    // it's a Sunday!
  }

Successfully Stopping a ZeroMQ Receiver

Thursday, June 23rd, 2011

ZeroMQ

Late yesterday I realized that I had a nasty problem with the ZeroMQ receiver component in my ticker plant codebase. Basically, if the publisher stopped before the client did, then there would be no clean exit for the client as it'd be stuck in a ZeroMQ zmq::socket_t::recv() call, and there's no timeouts or interruptions from that guy. I hadn't figured this out because ticker plants are almost always ticking, and so it was easy to stop the clients. Also, stopping and starting a publisher is easy, but I'd never planned on the use case of the publisher shutting down and not coming back up, and the client needing to quit. Well... my mistake, to be sure.

Now we have to fix it.

The idea I came up with was nothing special - have every new zmq::socket_t bind to a unique inproc: URL so that there exists a "back door" to send it messages - quickly. I can then continue on as normal, but in my shutdown() code I can tell the thread to stop, and on the off-chance that the thread is in zmq::socket_t::recv(), I'll connect to that same inproc: URL and send it a zero-length message. This will cause it to break out of the recv() call, and then it'll detect that it's supposed to shutdown.

The code is pretty simple, but even there, it took a few times to get all the pieces of the inproc: connections working. In my initialization code I now have:

  // nope... so let's make a new socket for this guy
  mSocket = new zmq::socket_t(cContext, ZMQ_SUB);
  if (mSocket == NULL) {
    error = true;
    cLog.error("[initialize] couldn't create the ZMQ socket!");
  } else {
    // ...and subscribe to all the messages
    mSocket->setsockopt(ZMQ_SUBSCRIBE, "", 0);
    // we need to set this guy up properly
    mSocket->setsockopt(ZMQ_SNDBUF, &__sndbuf, sizeof(__sndbuf));
    mSocket->setsockopt(ZMQ_RCVBUF, &__rcvbuf, sizeof(__rcvbuf));
    mSocket->setsockopt(ZMQ_RATE, &__rate, sizeof(__rate));
    mSocket->setsockopt(ZMQ_RECOVERY_IVL_MSEC, &__rec, sizeof(__rec));
    // let's get a new, unique instance number for this socket
    uint32_t   inst = __sync_fetch_and_add(&cInstance, 1);
    char    name[80];
    snprintf(name, 79, "inproc://sock_%d", inst);
    mBailOutURL = name;
    // now let's
    mSocket->bind(name);
  }

after I set the socket options with the calls to setsockopt(), I then atomically increment a class ivar that holds the next socket instance number. This, put on the end of the URL makes it unique, and then I save this so that my shutdown() code knows who to talk to.

Finally, I bind() the socket to this inproc: URL. This is important because in the case of OpenPGM/ZeroMQ, it's a callt o connect() regardless if you're a sender or receiver. Here, with the inproc: transport, it matters. The receiver has to bind() and the transmitter, as we shall see, has to connect(). OK. Got that cleared up.

In my shutdown() code, I now have something like this:

  void ZMQReceiver::shutdown()
  {
    // first, see if we're still running, and shut it down
    if (isRunning()) {
      // first, tell the thread it's time to stop processing
      setTimeToDie(true);
 
      // next, make the ZMQ socket for the inproc: transport
      zmq::socket_t    bail(cContext, ZMQ_PUB);
      // ...and set him up properly
      static int64_t   __rate = 500000;
      static int64_t   __rec = 100;
      bail.setsockopt(ZMQ_RATE, &__rate, sizeof(__rate));
      bail.setsockopt(ZMQ_RECOVERY_IVL_MSEC, &__rec, sizeof(__rec));
      // connect to the right inproc: URL
      bail.connect(mBailOutURL.c_str());
      // make a ZMQ message to send this guy
      zmq::message_t  msg(0);
      // ...and WHOOSH! out it goes
      bail.send(msg);
 
      // finally, wait for the thread to stop
      join();
    }
    // next, clear out all the channels and shut down the socket
    clearChannels();
    // ...but make sure the socket is really dropped
    if (mSocket != NULL) {
      delete mSocket;
      mSocket = NULL;
    }
    // let's drop the conflation queue and all it holds
    if (mMessageQueue != NULL) {
      delete mMessageQueue;
      mMessageQueue = NULL;
    }
    // ...and clear out the commands to the socket
    mCommandQueue.clear();
  }

It's a little complex, but it's really worth it. We have a way to use the blocking recv() for efficiency, but we also have a way to shut it down. That's pretty nice.

GitHub for Mac is Released!

Wednesday, June 22nd, 2011

GitHub Source Hosting

I have to admit that git is an amazing source control system. It's what I have been looking for for a long time, and it fits perfectly into the way I write code. So when GitHub sprang up, I loved it! What a great place. You can do issue tracking, forking... it's amazing. Well... today they outdid themselves. They released a Mac git client: GitHub for Mac.

It is a beautiful git client for the Mac with all the features you'd expect, but the added bonus is that they have complete knowledge of the GitHub API v3, and it's integrated into the app. This means all the things that might be hard, or time-consuming can be made very simple and easy with the client app because it has inside knowledge of the "other side" - sitting on GitHub.

Traditional and GitHub. Amazing combination.

I'm not a huge Git GUI user, but this is my preferred tool for sure. Simply amazing.

Base 2.1 is Out

Tuesday, June 21st, 2011

Base 2.0

This morning I noticed that Base 2.1 was out. It's a very nice SQLite3 database tool for the Mac with some really nice looking graphics and very good speed. I've been a paid user since v1.0, and seen it get better and better. I just like SQLite3 and think there's a lot of smarts in using that for CoreData. Just wish I had more time to mess with it.

Nice tool. Great update.

Google Chrome dev 14.0.797.0 is Out

Tuesday, June 21st, 2011

Google Chrome

This morning I noticed that Google Chrome dev 14.0.797.0 was out, so I updated to see what's new. It seems that there's a new V8 engine (3.4.4.0) as well as improved print performance and a few Mac-specific things with the text areas and voice over. Nice, but nothing really amazing at this point in the game. Sad to say, but the browser has pretty much stagnated - with the exception of HTML5 and JavaScript, it's pretty much the same things it was a year ago. Nice to see things mature, but it takes a little fun out of it when the major browsers are all really the same.

Google Chrome dev 14.0.794.0 is Out

Friday, June 17th, 2011

Google Chrome

This morning they 'jumped the version' and the Google Chrome team put 13.x into 'beta' and started the dev series with Google Chrome dev 14.0.794.0. This guy is supposed to have the latest V8 javascript engine - 3.4.3.0, and quite a few fixes on different platforms. It's the inevitable march of progress for Chrome, and it's getting a little boring, to be honest. There's nothing really new coming out of that group, and in a way, that's OK. Browsers are OK to be boring - they are supposed to get out of the way and let the user to their thing. So OK... I'll give them boring.

Setting SQLAPI++/iODBC/FreeTDS for Minimal Impact

Wednesday, June 15th, 2011

database.jpg

This morning I spent a little time looking at the SQLAPI++ manuals looking for the way to make it minimal impact on the SQL Server I'm hitting. I was hoping to find a way of setting a timeout on the SQL statement's execution. What I'm seeing now is that every so often the act of reading from the database will hang the thread doing the reading, and it doesn't give it up for long enough that I restart the process.

This isn't good.

So I wanted to put in a timeout without resorting to a boost ASIO timeout. What I found was that there isn't a timeout in the SQLAPI++ code, and there isn't really one in the iODBC layer, either. There is one in the server configuration on FreeTDS, but I'm not really keen on putting a timeout value there for all connections and queries to a database. I just wanted to be able to put one on this set of queries.

What I did find was that I could make the SQLAPI++ command quite a bit nicer to the database with a few options on the command:

  cmd.setCommandTest(aSQL.c_str());
  cmd.setOption("PreFetchRows") = "200";
  cmd.setOption("SQL_ATTR_CONCURRENCY") = "SQL_CONCUR_READONLY";
  cmd.setOption("SQL_ATTR_CURSOR_TYPE") = "SQL_CURSOR_FORWARD_ONLY";
  cmd.Execute();

where the middle three lines are new this morning. The default for the command is to fetch only one row at a time - that's very bad, and to allow a more liberal reading/updating policy with the cursor. I don't need any of that, and this will make sure that I'm about as lightweight on the database as possible.

With no timeout to fall back on, I'll have to just see if these changes are enough to make sure I don't get the lock-up again. Sure hope so...

Adium 1.4.2 is Out

Monday, June 13th, 2011

Adium.jpg

Over the lat few days, it's been clear that there's been a problem with Adium 1.4.2b2 and ICQ. Basically, ICQ is saying there's no connection, or the developer ID is wrong - lots and lots of problems. I checked earlier today on the Adium IRC channel to see if they knew this was going to be fixed in an upcoming release. What I found was that ICQ is big in Germany - who knew? Anyway, 'yes', it was going to be fixed in 1.4.2 final, and I just needed to hang on.

I then asked if they had even an estimate on when that might be released - as I'm really tired of all the errors and alert klaxons going off. They said that they hoped to release it today. Very nice!

Sure enough, a few hours later, I got a tweet that Adium 1.4.2 was out, with a pretty nice list of updates. The lone problem was that the version of libpurple (old 'gaim code') had a few nice MSN features, but in three areas, it slipped backward. The Adium developers decided to go for the greatest good for the greatest number, and use the new libpurple, and slip on the three features. Evidently, it made some MSN users less than happy.

I can understand their concern, but at the same time, I can see why the Adium developers did what they did. They didn't write libpurple, and they have to take it as-is and use it. They then just have to decide which version to use, and to them, the greatest good was in moving forward, and the unfortunate consequence was that a few things slipped.

I'm sure it'll be updated soon to 1.4.3 with a new libpurple, and that's OK too. It's what the group needs to do. I just don't see people getting that upset about it. But then again, I don't see a lot of things...

Forked Gist Vim Plugin

Friday, June 10th, 2011

GitHub Source Hosting

This morning I was looking to see if anyone had updated the Gist Vim plugin to support the other functions that I haven't yet gotten time to check on. I found the someone had put it up on GitHub, and checked to see if their repo had the fix I made to the plugin yesterday. He hadn't. But that got me to thinking - Why don't you fork it, and fix it yourself? So I did.

I've now got a repo at GitHub for my fork of the Gist Vim plugin that does a few things that the original didn't:

  • Pulling a Gist doesn't split the window - it takes the whole buffer
  • Pulling a Gist works with the new API v3 GitHub spec

I pushed it up - worked like a charm, and now I've got a place to keep this bad boy up to date. I still haven't had time to look at the other functions, but I will, and I'll fix them, if needed. The scripting language is pretty nice, and I can't imagine I'd need anything it doesn't support.

It's silly, but this is my first fork on GitHub, and I'm really pretty giddy about it. Jazzed, even.