Archive for October, 2018

Big Download Morning

Wednesday, October 31st, 2018

Software Update

This morning there was a flurry of downloading, and while I expected iOS 12.1 because of yesterday's Apple Event, I didn't expect to see macOS 10.14.1, and then Xcode 10.1 - but in truth, the emoji updates in iOS 12.1 had to be mirrored in macOS or we'd have some very funny looking tweets.

What I found interesting was that the App Store can have updates in it, and System Preferences has updates in it - and they aren't the same, but the System Preferences appears to be able to control the downloading and installing from both sources. That's good.

In the Apple menu, there are two items - App Store..., and System Preferences... and each of these had a decoration for the updates. It's a nice touch - classy, as always from Apple.

One of my Favorite Comments

Tuesday, October 30th, 2018

Code Monkeys

Many years ago, I built a market data server based on the Bloomberg API that was available on Solaris - back in the days when the Bloomberg Terminal was available on Solaris. In that code, I needed to solve a problem of thread starvation and in order not to confuse the Next Guy - which could have been me, I made sure to comment this code to get a reference to the "housekeeping mutex" in the object. This was all C++.

To this day, this is one of my favorite comments. It's just exactly what I want to write, tell people I think they can write:

/*
 * When any client or chat command wants to do something with the
 * server they need to get my housekeeping mutex and place a read
 * lock on it. The reason for this is that we are going to have
 * times when the controller knows that things aren't really stable
 * in the system and therefore we need to hold off on doing certain
 * things. Since this is a read-write lock, most of the time things
 * will run along swimmingly, but when there is maintenance underway
 * we will obtain a write lock and make the normal clients wait for
 * the maintenance to be done.
 */
CKFWRWMutex *BBGServerController::getHousekeepingMutex()
{
    /*
     * With so many readers (clients) hitting the server at all hours,
     * we run into the problem that the write lock is almost impossible
     * to get. This is further hanpered by the fact that the pthread
     * read-write mutex doesn't specify the writers as having a higher
     * priority than the readers. So we can get a writer starvation.
     *
     * The solution is to have another mutex "in front" of the read-write
     * mutex that controls everything. The way this works is that all
     * clients need to call this method to get the housekeeping mutex.
     * The first thing they'll need to do here is to get a lock on the
     * "out of order" mutex and then release it right away. Most of the
     * time this will happen with little to no delay. However... when the
     * major housekeeping tasks arise, they lock this guy and *leave it
     * locked* so that the write lock that comes after it can wait for
     * the pending readers to get done and *then* obtain it's write lock.
     * 
     * When the housekeeping maintenance is done, we unlock the write lock
     * and then unlock the "out of order" lock and this method can resume.
     * It's a clean process that allows me to prioritize the write lock
     * above the readers which is as it should be in this application.
     */
    mOutOfOrderMutex.lock();
    mOutOfOrderMutex.unlock();
 
    return & mHousekeepingMutex;
}

Writing comments like this just makes me smile.

Norsemen on Netflix is very Funny

Friday, October 26th, 2018

TV.jpg

I gave a look at Norsemen several months ago, and just couldn't get into it. But I know why now - the relationship between a character and his wife... it just reminded me of some painful memories. But hey... it is what it is. This is a funny show. Reminds me of Monty Python in many ways. The show has no laugh-track, or studio audience, so it's just the actors and the dialog.

What's so funny about this show is that the dialog is straight out of the current day - but the actions and people are still in the year 790. It's just what you'd expect from something like The Holy Grail. Very funny.

References to things like "Free Speech" and the jokes... it's just really funny, and the actors are just amazing. Worth a look.

UPDATE: OK... in the second season, the scene where one character talks about the dominos falling, and then explains it with "a chain reaction" - it's just too funny. I really like how they don't wait for people to laugh. They just say things that make no sense for 791 AD.

Simple File Encryption

Friday, October 26th, 2018

Yosemite

This morning I decided to turn on two-factor authentication on my GitHub account using the Authy app for my iPhone. I've been able to use it for different accounts, and it's always mine - not the company I work for, and while I've been using SMS for a while on GitHub - and others, I've just decided that it's probably a good thing to get moving on this = given the privacy issues that we are all reading about these days.

The thing that I needed was a simple file encryption bash script/function so that I could store the recovery tokens in a file without having to worry about it getting snatched. So now I've got it. The code is based on openssl, and it's pretty simple:

#
# These are simple functions to encrypt and decrypt files so that I don't
# have to hassle with extreme things in order to secure one file at a time.
# They use openssl to do the work, and it's pretty simple.
#
function jack {
    openssl des3 -in "$1" -out "$1.enc"
}
 
function unjack {
    openssl des3 -d -in "$1" -out `basename "$1" .enc`
}

and this simply allows me to encrypt a file and it adds .enc on the end of the filename, and then I can decrypt it as well, stripping that addition as well. Nothing fancy, but it really works just great.

The Real Cost of Bad Engineering

Monday, October 22nd, 2018

Bad Idea

This morning, I read this article about a problem in two small towns in Massachusetts when the engineers responsible for a normally reliable, safe, natural gas distribution infrastructure don't really think about what they are doing, and the consequences of their designs. It's shameful.

The NTSB report about what happened was very clear, and very troubling:

The contracted crew was working on a tie-in project of a new plastic distribution main and the abandonment of a cast-iron distribution main. The distribution main that was abandoned still had the regulator sensing lines that were used to detect pressure in the distribution system and provide input to the regulators to control the system pressure. Once the contractor crews disconnected the distribution main that was going to be abandoned, the section containing the sensing lines began losing pressure.

As the pressure in the abandoned distribution main dropped about 0.25 inches of water column (about 0.01 psig), the regulators responded by opening further, increasing pressure in the distribution system. Since the regulators no longer sensed system pressure they fully opened allowing the full flow of high-pressure gas to be released into the distribution system supplying the neighborhood, exceeding the maximum allowable pressure.

Why the control system wasn't smart enough to detect:

  • Pressure Reading of Zero - the sensor was on the abandoned line - which had no pressure. Why didn't that fact alone cause an alarm?
  • Zero Change on Output based on Input Change - when the first change was done, why wasn't the change seen on the sensor - at least in a percentage measure? Even, if you look at the first-derivative of the sensor reading, a simple thing to do even with analog control systems, and see that no change could be seen should have been an error.
  • Upper Limit on Input - when you see that you have increased the input some percentage in the last "...few minutes..." - then sound the alarm. There is no reason to ramp the input like this. It's a leak - or worse, and needs to be corrected.

Carnage of Natural Gas Overpressure

As an engineer, I'm stunned that the folks that created this control system didn't do these, or something similar, to them to sound alarms as opposed to letting four homes blow up. I mean, it's one thing to have a leak, with a bad scent in the house - but to actually have homes blow up - that's way past bad design.

An old friend and I have talked about this many times over the years - How do you really teach this kind of design? - and it's not easy. It comes from experience, and the problem is, most engineers don't have it - any more than most people are wise. You have to accumulate experience over years - to know what to think about... what to look for... all that needs to be considered, and it takes years to really gain that perspective.

But companies will pass things like this off to the junior engineers - because that's who they believe can do all that's needed. And if you ask the folks doing the work if they are ready to do this kind of work, they are always going to say "Yes!". That's just "confidence".

Until we come to terms with this gap in the education of engineers, we're going to have these problems, and they could be a whole lot worse.

Fun with FORTRAN and Sublime Text 3

Wednesday, October 17th, 2018

Sublime Text 2

Today I decided to open up some of the fortran code I wrote for my thesis - 30 yrs ago, and see if Sublime Text 3 would handle the syntax highlighting, and therein brought up an interesting point about the problem I had in upgrading from Sublime Text 2 to 3. So it made sense to write it all down just in case it happens on another upgrade in the future.

I found a nice Fortran package Sublime Text 3 - it did all the normal syntax highlighting stuff, and lots more. Very slick that it picks out the LaTeX formatting in the comments - Who thinks of this? Wild! So it seems like a great little find. Sweet.

I go to install it, using Package Control, and I noticed that Package Control wasn't installed. That's odd... I know I had it installed - maybe it didn't come over in the upgrade? So, let's install it again... No biggie.

Well... kinda... When I following the installation instructions, I didn't see it show up in the pop-up. Very odd. I checked the directory structure - it was there... but it wasn't showing up. Very odd...

So I Googled the issue, and it seems that it's something that happened enough to warrant a tip - it might be disabled. Go to the general settings, a JSON file, and then see if it's in the list of disabled packages. Sure enough - there it was! I simply deleted it from the config, and restarted Sublime, and Bingo!

After that, everything was working just fine:

Bias F in Sublime Text 3

We have Created Our Own Monsters

Tuesday, October 16th, 2018

cubeLifeView.gif

I know we all just want to have some sense of satisfaction in our lives. To feel that we matter - somewhere. To feel that we make a difference. It's universal... but so many don't have that because of circumstance or society. But that's another issue. What we, in the US Tech Industry have created is a class of people that feel entitled to things that they have no entitlement to. My sister calls these The Soccer Trophy generation.

If someone is told - at every possible turn - that they are amazing, valued, better than the rest, then their sense of reality is being formed in those moments. If all you allow a person to see is a mirror, reflecting back to them that they are the center of the world, then they have no opportunity to see what reality is like outside those mirrors. It's not surprising then, when these people get angry when the context is changed, and it's time to work together with others of differing opinions, and then all of a sudden, things go very badly.

Over the last five years, I have been working with folks that fit this profile perfectly. They are fine people - at least in comparison to most federal inmates. But they are employees that feel the company owes them a sense of purpose, a job that fulfills them... and they have every intention of getting that. But that's not how the world really works. Sometimes it's just a lot of hard work for very little short-term payoff. Life isn't fair. But telling this to our little monsters usually creates such a stink that it's avoided at all costs.

I'm all for being nice. I'm all for being generous. I think these are fantastic qualities, and I try to be as graceful as I can be. All the time. But some days I just want to say "Someone did you a disservice by making you think the world revolves around you. It doesn't." Now let's have a little moment to deal with that, and let's get back to work!

But that's not done... Go figure.

Updating the JDK Versions

Thursday, October 11th, 2018

java-logo-thumb.png

This morning I noticed that Clojure 1.10.0-RC1 was out, and that it was setting a minimum of JDK 1.8 as the required Java version. That's not a problem, as that's what I've been using, but I thought it might be a good thing to get the lates versions of the JDK installed on my box, and make sure that JDK 10 and JDK 11 work with the setjdk Bash function I wrote to make it easy to change from version to version in the environment.

So I went to the java.com web site, and first noticed that the current version they are suggesting is JDK 1.8 - and that really surprised me. I have known that JDK 9, 10, and 11 have been out for a bit, but to see that Oracle is suggesting that a new user install JDK 1.8.0_181 - that's just a little surprising.

Also, they made it a lot harder to find the other versions of the JDK - maybe that's because there was more confusion than necessary for folks just looking for the latest JDK - but therein is kinda my concerned - JDK 1.8. Still... I found it and was able to get the latest JDK 1.8.0_181, JDK 10.0.2, and JDK 11 - they have clearly decided to change the versioning, which is OK with me - but it means that I really need to make sure that I check the setjdk function when I install these guys.

When I got them installed, they all looked in place:

  peabody{drbob}516: ls -lsa /Library/Java/JavaVirtualMachines/
  total 0
  0 drwxr-xr-x  13 root  wheel  416 Oct 11 10:29 ./
  0 drwxr-xr-x   5 root  wheel  160 Sep 24 19:00 ../
  0 drwxr-xr-x   3 root  wheel   96 Jun 29  2011 1.6.0_26-b03-383.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Oct 11 10:29 jdk-10.0.2.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Oct 11 10:29 jdk-11.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Feb  5  2013 jdk1.7.0_13.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Oct 16  2013 jdk1.7.0_45.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Jan 17  2014 jdk1.7.0_51.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Mar 20  2015 jdk1.7.0_75.jdk/
  0 drwxr-xr-x   3 root  wheel   96 May  1  2017 jdk1.8.0_131.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Oct  2  2017 jdk1.8.0_144.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Oct 11 10:28 jdk1.8.0_181.jdk/
  0 drwxr-xr-x   3 root  wheel   96 Mar 20  2015 jdk1.8.0_40.jdk/

and then a quick check of the setjdk script:

  peabody{drbob}504: setjdk 10
  peabody{drbob}505: echo $JAVA_HOME
  /Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
  peabody{drbob}506: setjdk 11
  peabody{drbob}507: echo $JAVA_HOME
  /Library/Java/JavaVirtualMachines/jdk-11.jdk/Contents/Home
  peabody{drbob}508: setjdk 1.8
  peabody{drbob}509: echo $JAVA_HOME
  /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home

This is the current cut of my setjdk function in my ~/.bashrc file:

  #
  # Clever trick to leverage the /usr/bin/java commands to take advantage
  # of the JAVA_HOME environment variable and the /usr/libexec/java_home
  # executable to change the JDK on-the-fly. This is so easy I'm amazed.
  #
  function removeFromPath() {
    export PATH=$(echo $PATH | sed -E -e "s;:$1;;" -e "s;$1:?;;")
  }
 
  function setjdk() {
    if [ $# -ne 0 ]; then
      removeFromPath '/System/Library/Frameworks/JavaVM.framework/Home/bin'
      if [ -n "${JAVA_HOME+x}" ]; then
        removeFromPath $JAVA_HOME
      fi
      export JAVA_HOME=`/usr/libexec/java_home -v $@`
    fi
  }
  setjdk 1.8

So now I can work with any version of Java out there. What I did find interesting is that they have pulled JDK 9 - and that means it was really bad. Like Wow bad... at least they knew to pull it.

More Fun with Xcode 10 and CryptoQuip

Wednesday, October 10th, 2018

xcode.jpg

This morning I dove back into Xcode 10 and CryptoQuip - this time fixing up the UI elements because I had the test string in the NSTextView and that was sloppy and there were no tips on the text boxes, and the hint was a pair of NSComboBoxs, and that wasn't as nice as the NSPopUpButton I'd used in the Swift version. So it was time to clean it up.

The first thing was to pull out the test string from the NSTextView and put in the tool tips on where to put what. That was simple... converting an NSComboBox to an NSPopUpButton was not as easy. I was hoping it was a simple object change, but it really had to be a remove-and-replace which wasn't horrible because the placement tools for Xcode 10 are really nice.

CryptoQuip Xcode Project

What was a little more painful was the fact that I needed to create all 26 values for the NSPopUpButton A-Z in the UI. There didn't seem to be a simple way to do it. And now that Xcode 10 has removed the Object Library from the UI, I had to find the new Library Search feature... very "Spotlight"-like, and not horrible, but it was a bit of a surprise to see it gone.

The final part was really cleaning up the code on the -decode: method. That was a mess because I was previously looking at each UI element in isolation, and that was a mistake. Also, I wasn't putting the values back... it was just a mess. So I decided to clean it up like:

- (IBAction) decode:(id)sender
{
  // get the values from the UI elements
  NSString*   cyphertext = [[self getCyphertextLine] stringValue];
  NSString*   cypher = [[self getCypherChar] titleOfSelectedItem];
  NSString*   plain = [[self getPlainChar] titleOfSelectedItem];
 
  // if there is no cyphertext, flip to the test case for testing
  if ((cyphertext == nil) || ([cyphertext length] == 0)) {
    cyphertext = @"Fict O ncc bivteclnbklzn O lcpji ukl pt vzglcddp";
    cypher = @"b";
    plain = @"t";
    // ...and feed all these back into the UI so it looks nice
    [[self getCyphertextLine] setStringValue:cyphertext];
    [[self getCypherChar] selectItemWithTitle:[cypher uppercaseString]];
    [[self getPlainChar] selectItemWithTitle:[plain uppercaseString]];
  }
 
  // now let's call the solver
  [self solve:cyphertext
        where:tolower([cypher characterAtIndex:0])
       equals:tolower([plain characterAtIndex:0])];
}

Now, we are looking at just the cypher text, and keying off that for the test case. Makes a lot more sense. Much better.

All builds and runs fine. Check it all in, and really happy with the way it all worked out. Looks a lot better.

Finally Updated my Resume

Tuesday, October 9th, 2018

cubeLifeView.gif

Some of the recruiting folks at The Shop have been asking me to update my LinkedIn profile so that I can be seen as working at The Shop, and get some additional recruiting cache - which I kinda doubt, but who am I to say? This morning, I decided it was time to help them out - I've put them off enough, and that's just not nice. So... it's updated.

I spent a little time on the HTML version for the web site as it wasn't showing the employer or city, and that was kinda important... so I had to work up the CSS to make it look right, and I have to say, I can't believe how much simpler it'd all be if I just always used divs, and then set the font properties and left it at that. Just crazy... but hey, at least it's done.

Now I can be the poster boy for The Shop as recruiting wants. Such is life, right?