Happy Birthday to Me!

December 31st, 2013

Cake.jpg

I don't know what's going to happen next year - heck, I don't know what's going to happen tomorrow. But I do know that today I'm another year older, and I'm hopefully a little wiser... I think I'm a little more compassionate - after the year I've had, I'd think I bloody well should be... and I certainly wish I was a little more comfortable with where my life is. But I'm working on that.

Certainly, I'm a work in progress, and while that's not the best thing for someone hitting 52, it's better than what it could be. I've had a heck of a year. It's not getting any better, and I have a lot of battles ahead of me still. There's the court appearance in a few weeks, there's the separation of finances, there's being a single parent to a trans gay son, there's the death of my brother-in-law, there's a lot of stuff that's happening in the next month, and I'm not at all sure I'm ready for any of it.

My faith says that I'm not going to be given anything I can't handle. I want to believe that's true, but it's hard to believe that I'm going to be ready for any of this, let alone all of it. But that's really not an issue, either, is it? Because it's going to come, and ready-or-not, I've got to press through all this and get through each day.

The good news is that it's only 5 minutes at a time.

That's how I'm moving forward - just 5 minutes at a time.

Everything else, is in His hands, and I firmly believe that this is my only way through all this. Do my best every day. Take things as they come, and only do what you can do - not what you can't. But only 5 minutes at a time.

I sure hope 2014 is a better year for me. I really do.

What Would I Build?

November 25th, 2013

Storm

I've been playing around with Storm for a while now, and while I don't think there are all that many folks in the world that are expert at it, I'm certainly an advanced novice, and that's good enough for the amount of time I've put into it. I've learned a lot about how they have tired to solve the high-performance computing platform in clojure and on the JVM, and I've come away with an affirmation of the feelings I had when I was interviewed for this job, and discussing functional languages: Garbage Collection is the death of all functional languages, and certainly Storm.

I like the simplicity of functional languages with a good library of functions. Face it, Java took off over C++ because C++ was the base language, and Java had the rich object set that everyone built on. It made a huge difference in how fast people could build things. So if you want a functional language to have a lot of traction fast, you need to make sure that you don't send people to re-invent the wheel to do the most basic tasks.

But the real killer is Garbage Collection. I'm not a fan, and the reason is simple - If I'm trying to do some performant coding, I want to control when that happens, and under what conditions. It's nice for novices to be able to forget about this and still write stable code, but when you want to move 1,000,000 msgs/sec, you can't do it without pools, lockless data structures, mutability, and solid resource control. None of which I get in the JVM - or anything based on it.

So what's a coder to do? Answer: Write another.

There used to be Xgrid from Apple, but they dropped that. They didn't see that it was in their best interests to write something that targets their machines as nodes in a compute cluster, and they aren't about to write something where you can use cheap linux boxes and cut them out altogether. Sadly, this is a company, and they want to make money.

But what if we made a library that used something like ZeroMQ for messaging, and then we used something like C++ for the linux side, and Obj-C++ for the Mac side and made all the tools work like they do for Storm - but instead of using clojure and the JVM, and a ton of tools on the server-side to handle all the coordination and messaging, let's use something that's far more coupled with the toolset we're working with.

First, no Thrift. It's bulky, expensive, and it's being used as a simple remote procedure call. There are a lot better alternatives out there when you're using a single language. Stick with a recent version of ZeroMQ and decent bindings - like their C++ ones. Start small and build it up. Make a decent console - Storm is nice here, but there's a lot more that could be done, and the data in the Storm UI is not really easily discernible. Make it clearer.

Maybe I'll get into this... it would certainly keep me off the streets.

Chasing the Magic Tool

October 28th, 2013

Storm

I'm in the midst of a new project here at The Shop, and I can understand that it's really new technology, and as such, very little is really known about it. Sure, if you listen to the conference talks, Storm is old news, but put it into production and all of a sudden a lot of people's hands lower in the crowd because it's just so bloody new. I'm trying to make it work.

But at the same time, I'm seeing emails about new distributed systems frameworks -- sounds a lot like what Storm is about, and management is asking for opinions. My initial opinion is pretty simple: Pick one and get good at it.

I'm here, but I'm worried that this place is the exact opposite of "Enterprise Tools" - they are the "Always Shiny". We have a tool for distributed, fault-tolerant, computing - so why are we looking at another? Should we assume that the selection we have is premature, and that based on what we have found, we need something better?

I'm not against competition, but then, you have to allow for the fact that you're going to have a hodgepodge of all kinds of systems in the end, as no one goes back and converts a working production system from one working tech to another, different, working tech. There's never time.

So why the search? Why not just get good at one of the leaders in the space, and then gain the critical experience to be able to really make it work?

I fear the answer is that too many people think the tool is the real power.

Nothing could be further from the truth. I've seen it done over and over again - what might be considered antique tech building some of the most amazing things because the people that used it knew it so well they were able to overcome the problems, and make amazing where a newcomer to the tech would see it as impossible.

I hope I'm wrong. I fear I'm not.

Oh, I am SO Guilty of This…

September 20th, 2013

I just saw this on twitter:

A common fallacy is to assume authors of incomprehensible code will somehow be able to express themselves lucidly and clearly in comments.

— Kevlin Henney (@KevlinHenney) September 20, 2013

…and for the first time in weeks it made me want to post something.

I'm so horribly guilty of this that I don't even realize it. When I look at poorly documented code, I think the author was just lazy - because he's as smart as I am - right? Maybe not.

In fact, probably not.

To this day I don't see myself as any smarter than a lot of the professional developers I have worked with. Sure, there are some really junior folks, but I'm talking about the seasoned professionals - those guys that may have been working in the web space for a while, or working on back-end systems, or library builders… they are all just as smart as I am. The only difference, so I thought, between them and me is that I worked so much harder that it was just a matter of effort.

This little gem of a tweet says in 140 characters what I keep missing over and over again - that when you look at really bad code, it's often times more likely that the author didn't know any better, or was using too much StackOverflow, and really had no idea what they are doing. So adding comments to this mess is only going to increase the line count and not really add value to the work.

I need to remember this more often.

Building Clojure Libraries for use in Storm

September 20th, 2013

Storm

Here's a little gem that I figured out while trying to deliver a nice clojure library for some storm work that I've been doing. The problem is that when you build an uberjar for a topology (or library) with leiningen, you don't want to include the storm jars as that will mess up the storm cluster when you go to deploy the topology. So how to get it to all work locally, but when building the uberjar, it goes smoothly.

Sadly, this is not clearly documented anywhere that I could find. But there were bits and pieces here and there and I was able to figure out what I needed with a little trial-and-error.

Thankfully, it's all in the leiningen project.clj file:

  (defproject having-fun "1.0.0"
    :aot [project.core]
    :profiles {:provided {:dependencies [[storm "0.9.0-wip16"]]}}
    :repositories [["releases" {:url "http://nexus/content/repositories/releases/"
                                :sign-releases false}]]
    :main project.core)

Where the keys seem to be that with leiningen 2, you need to accept that the :aot tag needs to be at the top level, and not buried in a :profiles entry. This seems to be a change going forward, so I wanted to adopt it now, and it works better this way.

Additionally, the :profiles line is all about excluding the storm jars in the uberjar, which is just what I needed, and then the :repositories tag is all about where to deploy this to with a simple:

  $ lein deploy

With this, I've been able to build clojure libraries with defbolt and defspout constructs - which is exactly what I wanted to do, and then put this up on our local nexus server so that it's very easy for others in the group to put this library in their project.clj file and make use of it.

Sweet.

Breaking Production – Not Good Leadership

August 9th, 2013

Bad Idea

This week has been a little stressful for me - I've spent a few days off work getting the last of my things out of the house and into storage, and then signing some papers to sell the house. It's all a necessary part of life, I know, but it's stressful, and so I have to push through it.

What I didn't expect to have to deal with was a broken production app that supports some of the capabilities of the main project I'm on at The Shop. It's not a lot - it's not really looking all that great, but it's really useful to me in what I'm doing, and I depend on it every morning for writing up a status email that I send to the group about the overnight runs.

Anyway, for two days in a row one of the senior developers in the group - a relative newcomer, has broken production. The first day, I was pretty nice about it - just asking him if he checked production once he deployed the changes, and knowing full well he hadn't. The next day I was not as happy, and it started a significant email chain with him, the group manager, and myself about what we should be doing, and the qualities of leadership, in general.

The problem is that this guy was hired to be the Tech Lead of the group, but he's never really lead in a way that I felt worth following. He could certainly command, but that's not how groups at The Shop are run - it's meant to be a consensus of smart guys arriving at a good decision for the good of the team and business. There will certainly be differences of opinion, and our group has had many, but after a good talking session, we understand everyone's position, and consensus is reached. It might not leave everyone happy about things, but it works.

At least it used to.

Now it's not working, and I've tried to give it several months to work itself out. But after the second day in a row where no testing was done after deploying changes to production, I felt it was time to point out that this casual approach to production has to stop. That it's very simple to test when it's in production, and the lack of even the simplest of testing is really a sign of a much larger problem.

I could try to make light of the real problem, but it boils down to attitude. Always does, doesn't it? If you have to proper attitude about your work, then you care about how it's seen by others. You are careful about changes. You watch the details and make sure they are all covered.

Basically, you do a good job. Regardless of the job. Carpenter, Dentist, Doctor, Coder - all are the same. If you take care in what you are doing, the end result may not be perfect, but it's at least something you can defend as being the very best you can do.

In this case, he knew it was a mistake. And to do it two days in a row was - well… really inexcusable. So I pointed out that leadership is an isolated job - it's up to others if they choose to follow you. Command is an entirely different thing, and I think we have a problem with the words and definitions we're using for this position. He may have been hired as the lead, but it presumed that he was capable of doing that job. For me, at least, he can't.

I don't know what will happen. I doubt if The Shop will re-arrange staff to suit me, but it's possible that I can have my project separated to make it easy to not have to face the daily friction of dealing - or in my case not dealing with him. I hope that's the case, but I don't know that they will do that. If not, it's been clear that there are other groups in The Shop that would be glad to have me help them, so it's not all that bad, but it's uncomfortable now, and I've been able to keep it very professional and positive.

What gets me is that the original members of this group would have laughed a bit at the first day, and then roasted him alive on the second. That we have gotten to this point is very sad to me. I miss the old team.

Letting Go – Regardless of Consequence

July 31st, 2013

cubeLifeView.gif

I like what I do - I really do. I like the company I work for - there are a lot of nice folks here, and I generally like the decisions that management makes. But as with every life a little rain must fall, there are times that your time in a group is done, and it's best to move on. The ideas that shaped the group and got it to this point were necessary and good, but now it's time to let someone else take over and take it from here.

Of course, that's not how it feels.

It feels like the new folks to the business think they have a monopoly on the project even though they just joined the company. It feels like they have no respect for the ideas the project was built on, so that their changes to the codebase make no sense, and in fact are counter to the goals that the project was built on.

It feels like they are being jerks.

And who knows… maybe they are. Maybe they aren't. It's not only impossible to tell, it's also completely unimportant. You find yourself in the minority and it's time to move on. No anger, no grief… maybe a bit of sadness for what's been lost, but loss is part of life. You can't allow the project to be what the new blood wants it to be - sees it to be in their minds, if you're there holding them back.

It's also not really fair to just sit in the group and allow the changes to occur around you. That's just gold bricking. Yeah, you know the code, yeah, you like the project, but it's all going in a different direction and it's time to just cut the cord. Allow the project to be what it will be under their stewardship.

It's time for me to move out of this group. As much as I'd like to keep working on what I'm doing, it's not good for the group or me.

Installing Hadoop on OS X

July 17th, 2013

Hadoop

This morning I finally got Hadoop installed on my work laptop, and I wanted to write it all down so that I could repeat this when necessary. As I found out, it's not at all like installing CouchDB which is about as simple as anything could be. No… Hadoop is a far more difficult beast, and I guess I can understand why, but still, it'd be nice to have a simple Homebrew install that set it up in single-node mode and started everything with Launch Control, but that's a wish, not a necessity.

So let's get into it. First, make sure that you have the SSH daemon running on your box. This is controlled in System Preferences -> Sharing -> Remote Login - make sure it's checked, save this, and it should be running just fine. Make sure you can ssh into your box - if necessary, make the SSH keys and put them in your ~/.ssh directory.

Next, you certainly need to install Homebrew, and once that's all going, you need to install the basic Hadoop package:

$ brew install hadoop

at this point, you will need to edit a few of the config files, and make a few directories. Let's start by making the directories. These will be the locations for the actual Hadoop data, the Map/Reduce data, and the NameNode data. I picked to place these next to the Homebrew install of Hadoop so that it's all in one place:

  $ cd /usr/local/Cellar/hadoop
  $ mkdir data
  $ cd data
  $ mkdir dfs
  $ mkdir mapred
  $ mkdir nn

At this point we can go to the directory with the configuration files and update them:

  $ cd /usr/local/Cellar/hadoop/1.1.2/libexec/conf

The first update is to handle a Kerberos bug in Hadoop - a known bug. Do this by editing hadoop-env.sh to include:

  export HADOOP_OPTS="-Djava.security.krb5.realm= -Djava.security.krb.kdc="

Next, edit the hdfs-site.xml file to include the following:

  <configuration>
    <property>
      <name>dfs.data.dir</name>
      <value>/usr/local/Cellar/hadoop/data/dfs</value>
    </property>
    <property>
      <name>dfs.name.dir</name>
      <value>/usr/local/Cellar/hadoop/data/nn</value>
    </property>
    <property>
      <name>dfs.replication</name>
      <value>1</value>
    </property>
    <property>
      <name>dfs.webhdfs.enabled</name>
      <value>true</value>
    </property>
  </configuration>

Next, edit the core-site.xml file to include the following:

  <configuration>
    <property>
      <name>hadoop.tmp.dir</name>
      <value>/tmp/hdfs-${user.name}</value>
    </property>
    <property>
      <name>fs.default.name</name>
      <value>hdfs://localhost:9000</value>
      <description>The name of the default file system.  A URI whose
      scheme and authority determine the FileSystem implementation.  The
      uri's scheme determines the config property (fs.SCHEME.impl) naming
      the FileSystem implementation class.  The uri's authority is used to
      determine the host, port, etc. for a filesystem.</description>
    </property>
  </configuration>

Finally, edit the mapred-site.xml file to include the following:

  <configuration>
    <property>
      <name>mapred.job.tracker</name>
      <value>localhost:9001</value>
      <description>The host and port that the MapReduce job tracker runs
      at.  If "local", then jobs are run in-process as a single map
      and reduce task.</description>
    </property>
    <property>
      <name>mapred.local.dir</name>
      <value>/usr/local/Cellar/hadoop/data/mapred/</value>
    </property>
  </configuration>

We are finally all configured. At this point, you need to initialize the Name node:

  $ hadoop namenode -format

and then you can start all the necessary processes on the box:

  $ start-all.sh

At this point, you will be able to hit the endpoints:

and using the WebHDFS REST endpoint, you can use any standard REST client to submit files, delete files, make directories, and generally manipulate the filesystem as needed.

This was interesting, and digging around for what was needed was non-trivial, but it was well worth it. I'll now be able to run my code against the PostgreSQL and Hadoop installs on my box.

Sweet!

Maybe I need to make a “List”

June 13th, 2013

GottaWonder.jpg

I've been having a hard time of it lately - Liza's filed for divorce, I know there's not a thing I can do about it, and the pain is only just beginning. At work, the dynamics in my group are changing quite a bit due (understandably) to a massive influx of new people - including the new manager of the group, and the new tech lead. The group needed the people - no doubt. We've lost a lot of people in the last six months, and things were starting to really get hectic, so it's nice to have the new hands, but there's just no way to double the size of the group and have it not change the dynamics of the group. And adding them all with a span of two weeks is a real shock.

So things are pretty jumbled at work, and I'm trying to come to terms with this newly evolving dynamic, and see how I fit in - even if I fit in, as there's no reason that this group still needs me as we now certainly have enough hands to get the work done in a timely manner. I'm not saying that I want to do something different now, but that if the new dynamic of the group is something that I don't fit into well, then maybe it's time to look for another group in the company where maybe I fit in better.

And all that got me thinking of things I might want to do.

I don't really have a lot of things that I want to do with the rest of my life - I think I've lead a pretty amazing life, and been able to do all the things I wanted to do. I taught at a University, and enjoyed it. I started a company and helped build it to $1 mil/year. I've been in finance and built some amazing performance code. I've seen most of the places I want to see (who sees everything?), and there just aren't a lot of things - big things, that I want to do.

But that doesn't mean I'm all done. Not by a long shot.

I want to get back into Mac development - and not just developing on a Mac - but developing for a Mac. I really like ObjC as a language, and the tools like Xcode are just amazing to me. Sure, I wish we had the old Project Builder multi-window format back, but what can I say? Old Schoool. But it's amazing, and what I've read about in Xcode 5 is also really neat. I've used the unit testing in Xcode 4, and it's pretty nice. To be able to set this all up on a Mac mini is pretty sweet.

So maybe I need a list. A list of the things I want to do.

Like maybe live in a different country and work there. Once the divorce is final, I'll be free to move to another country, and Liza can cry me a river if she doesn't like that I took a smaller paycheck for a better job. It's something I may want to do.

Maybe I should look at just moving to a different state? A good friend is ready to move to California as he and his wife are sick of the Chicago weather. Lots of questions there, but working for Apple might be really interesting. Who knows?

Maybe I could head back to making chips - or teaching at a University again? Maybe just start a Mac development shop and do it all myself? These are the things I'm thinking about, and as I'm thinking about them, I'm a lot more excited about them, than I am at the idea of more arguments in the group I'm in.

I have enough turmoil in my life right now. I don't need more. Really. No more. But I can't sit by and be passive when I feel strongly that the decisions that are being discussed (and made) are heading in the wrong direction for this project. The concept of a good group works because people all care about the outcome, and they all bring their ideas together and try to make the best decision possible.

I am fine with the discussions. I just can't stand the arguments. And right now, it's far more of the latter than I'm comfortable with.

Month Five of My Second Chapter

June 3rd, 2013

Sad State of Affairs

I'm not sure I want to call it My Most Painful Year anymore. I think it certainly still is, and there's no signs of it getting anything but more painful in the months to come, but I think I'm giving it the wrong emphasis. Yes, it's painful, and Liza seems to be doing her best to make it as painful as it can possibly be, but that's her choice, and while it may be her focus this year, I'm starting to think that it shouldn't be mine. Maybe I shouldn't have a focus?

Liza is going to get what the law says I have to give her. The lawyers will hash it out, and I'll force her to spend as much of her part of my money as possible to make her realize that she needs to take less and less in order for her to keep more of it in the end. After all, lawyers will love to burn up my money on both sides of the table.

But as much as I want to make her aware of the pain she's causing me, I think she knows. Her Dad is embarrassed by her actions. He says it's a "nightmare" that he just wants to wake up from. I know she values his opinion, so it's got to be tough to see her Dad taking my side in this. But it's not enough to make her care about me - and that, my friends, she never did.

So I have to try and just stay in the moment. Not focus on anything too much. Just like running, I need to put some miles between myself and this event. Get as much distance as quickly as possible before I turn back to try and get a little perspective on it. I'm too close right now, and that only makes looking at it painful and hard. But that's honestly to be expected. So I have to stop doing that as much as possible, and just focus on the running.

Once I get sufficient distance, I'll be able to look back, and not feel it so intensely. But I know that's going to take a lot of time.