Archive for April, 2015

Atom 0.194.0 is Getting a Lot Better

Thursday, April 30th, 2015

Atom Editor

With all the brew-ha-ha about GitHub's Electron and Atom editors, I wanted to give Atom another look. What I found was that it's amazingly close to an editor that I could use on a daily basis - moving Sublime Text out of the way.

They have solved the "re-opening with old files" issue - that was huge. They have gotten to the point that it even matches the command keys of Sublime Text. It's close.

There are a few things that are annoying... the command palette on the default Atom Light UI is too wide for my 80-column windows, and I can't for the life of me figure out what the CSS is to make it more narrow - like 90% of the display width. Fix that, and I might think about it.

OK... this is cool... get into the developer mode:

  $ atom --dev

and then you can get the standard WebKit Inspector for all the components. Then it's just a matter of making the element visible, inspecting it, seeing what's the dimension settings, and then fixing it.

In Atom -> Open Your Stylesheet, you can then add this little snippet:

  atom-panel.modal, .overlay {
    width: 90%;
    max-width: 500px;
    margin-left: 0;
    transform: translate(-50%, 0);
  }

and then the pop-up modal windows will be 90% of the width, and centered. Now it'd be nice to have this be limited to 500px, but I'll work on that next. For now, it's pretty close to being usable. I'll have to give it a go.

UPDATE: by adding the max-width and the transform tags, as well as setting the default margin-left, I can get it to be 90% and centered, or up to 500px and centered. Very nice!

connect bar

Command-and-Control Costs

Wednesday, April 29th, 2015

Management.jpg

Today I'm trying to appease management after being told that my promise to the CEO wasn't being covered by the CEO, and whatever management wants, management gets. And so I've finished the work I know needs to be done... given copies of the database to others for their use, and then emailed a few things about the production set-up. In all, it's been a good day. But now I'm stuck. Nothing to do.

So it's struck me that this compartmentalization of people and concerns is nice when you're dealing with insurgent cells, but it's kinda silly when you're in a business environment, and there are people that would help - if they only knew what they could do. This compartmentalization is a real killer of productivity - and morale, but let's stick with the real measurables - productivity.

Having one person control everything is a Bus Problem at the top - a bus hits this one guy and no one knows what was supposed to be done, or how things worked together, or anything. Cut of the head and the snake dies. I'm pretty sure that's something to be avoided.

Having one person control all the communication is inefficient as it places all communication in a serial queue that has but one actor: the processor. If he is busy, in a meeting, out for the day, on vacation, then nothing can be done because no one has the ability to process his messages. That's another form of the ...head of the snake problem, but it will occur no matter where in the organization this person is. Doesn't have to be the head.

All scheduling has to go through this one person, and that means that it's incredibly hard for them to effectively react to quick changes in individual's productivity. They dish things out - as they see fit - not asking anything - not sharing any plans - and so it's hard to adjust the plans when you aren't putting several minds towards the task.

The funny thing is that I don't believe they want to be treated like this - they just feel that it's their right to treat us this way. So sad... such a waste...

The Cost of Keeping a Promise

Friday, April 24th, 2015

Path

Yesterday was a very bad day for me. Yeah, to be fair, it's just one more in a long line of very bad days, but they tend to have a cumulative effect... after more than 5 or 6, it gets really hard to have the reserves that you had before the first. I'm not going to get into what it was, or anything like that - it's not the important point right now. What is important is that this morning I realized that it's just the cost of keeping a promise.

And yeah... it's just that simple.

A few weeks ago, I promised the CEO, in response to his worry about hitting a delivery date, that I would guarantee completion - but I had to be able to do it my way. It would work, and it would be stable, and flexible, but I couldn't be forced into another language, or another platform, etc. He agreed, and from that point on, even sub-consciously, I was working on that promise. When a new manager appeared, I assumed he was here to assist me. He believed he was here to implement his vision.

He didn't like that I wasn't willing to do just exactly as he said. I can even see his point of view - if it weren't for this promise I made. I should have told him right then and there of the promise, but I didn't want to make it more complicated than it already was. He wasn't interested in me liking his decision, he just wanted me to do it. That attitude just seemed wrong for the fact this was his second day.

But back to the point. This promise I made put me in the cross-hairs for his anger. It made me look to some like I wasn't being responsive - or even responsible. I was even painted as insubordinate. And what I realized this morning was that whether or not this was true, it was the cost of keeping the promise.

When I talk to the CEO and this new guy next, I'm going to ask the CEO if he wants to release me from this promise. If he does, then I'll do just what the new guy wants. Because then it's not my promise that's on the line. And it doesn't matter that the new guys says it's now his problem - the promise was from me to the CEO -- the new guy doesn't enter into the picture at all.

A great scene from Rob Roy:

Son: Father, will the MacGregors ever be kings again?
Robert Roy MacGregor: All men with honor are kings. But not all kings have honor.
Son: What is honor?
Robert Roy MacGregor: Honor is...
[Mary looking on]
Robert Roy MacGregor: what no man can give ya. And none can take away. Honor is a man's gift to himself.
Son: Do women have it?
Robert Roy MacGregor: Women have the heart of honor. And we cherish and protect it in them. You must never mistreat a woman, or a lame man. Or stand by a see another do so.
Son: How do you know if you have it?
Robert Roy MacGregor: Never worry on the getting of it. It grows in you, and speaks to you. All you need do is listen.

That's it. A promise is a promise - no matter what. Even when it's costly.

Moved to JDK 8 for Clojure Work

Friday, April 24th, 2015

java-logo-thumb.png

It had to happen... JDK 7 is end-of-life by Oracle, and while I imagine that this is not what is really going to happen to all the JDK 7 code out in the wild, it's enough of a pressure that it's time to move off it and onto JDK 8 for real.

I've got a nice switcher tool for the active version of the JDK for each shell, and I just switched it to 1.8, and restarted the REPL and web server to pick up the changes. It's not a ton of work, but it needed to be done, and I need to stay on JDK 8 moving forward.

It's funny... in writing this post, I realized that I can remember when JDK 1.5 was "new" and untested... and 1.6... and 1.7... it's just how things go. Marching onward.

Quite the Unusual Exchange

Tuesday, April 21st, 2015

PHB.gif

Today I had another in a series of very unusual exchanges with a new guy at The Shop that was brought in to assist me in getting a few things finished up in time for an upcoming release. He was brought in - as I understood it - to be the heat shield for me to enable me to get a lot more done with someone cutting through the red-tape and such. It's not like this is Rocket Science, but it'd really help to have someone running interference for me, and then I'd be able to stay focused and writing code. But that's not how this first week has been turning out.

The guy is nice. I don't believe he's a mean or nasty person at all. I think he's got skills, talents, and drive - all good things. I think for a lot of people, this guy would be great. But for me... for this project, it's not really working out. Yet.

This project is supposed to be about getting something done. There are plans for longer-term solutions in the works, but they are going to take time to build and get up to production standards. If they were running now, there'd be no point in the work I'm doing - we'd get data from external sources, and simply throw it onto Kafka, and the Big Data Team would take care of it. It's a good solution.

If it were built.

But it's not.

So in order to meet timelines, I believe we agreed to have something more short-term that would hold off the need to rush the implementation and do a poor job. Everything I've heard reinforces that - save all the conversations with the new guy. To him, this is an opportunity to build a replacement for the Big Data - and do it at scale.

To me it's a classic Don't use a hand grenade to kill a mosquito - but to him, that's just a matter of opinion. And in truth, I suppose it is. Depends on the size of that mosquito.

He wants the problem broken down into different phases - services, and then different database tables, and all that would certainly work, but it's far too much and too complicated for what we need, and we have the time factor against us. The more complex we try to make this, the greater the risk we won't finish on time.

But that's not the odd part about this exchange today... No, today was about the order of building things. He wanted me to build all the acquirers and parsers and then worry about what to do with the data, where I have done enough of them to know that I don't need to do more, but the architecture I've picked might be wrong if I run into something I don't expect in the subsequent processing of the data. So I wanted to finish one or two of the sources all the way to completion, and then go back and finish the rest.

He disagreed. He said that he understood, but it's what He wanted that counted, and he wanted all the 'first stage' work done.

I tried to talk to him about my concerns of the risks to having to go back and re-work the code - as I'd already had to do for persisting the data to the filesystem, but he wasn't swayed. In the least.

He kept at it - asking me "Are you going to do it?" - seemingly waiting for me to say "No." I told him I didn't want to lie to him - to tell him I'm doing one thing when I'm not. And that I didn't feel at all comfortable with his plan - for this part of the project. He wasn't swayed.

In the end, I had to say "I can't."

I have no idea what the upshot of this is going to be. I worry it won't be good. But maybe it was a test? Maybe he wanted to see how I'd respond to a stressful situation? Maybe a lot of things. I just don't know.

I told my HR rep, as she has been up to date on this from the beginning. I don't expect anything from HR, but it's important to understand that when I was being insubordinate, there was a reason, and it was for the good of the company. I don't know if it'll make any difference. We'll have to wait and see.

Upgrading Postgres 9.3.4 to 9.4.1 Using Homebrew

Monday, April 20th, 2015

PostgreSQL.jpg

This morning I didn't have a lot going on, and I decided to upgrade my laptop from Posgres 9.3.4 to 9.4.1 as there are a few little things in 9.4 that are nice, and I've got 9.4 on my work laptop, and I figured this would be an easy upgrade - like super easy... I was mistaken.

The rules about automatic upgrades for Postgres is a bug release version change. I thought it was a minor release. So I was expecting to simply shut down the server, upgrade the packages with Homebrew, and then start it back up. The code would detect that it was the next minor version, and automatically update the data. Sadly, that's not the case. It's a big upgrade, and that means that I might as well do a complete dump/load.

Sadly, I didn't do a dump, so I'd have to live with an older version. Not a tragedy, but annoying when I'm in the middle of the upgrade process only to learn that it's not going to work. So it goes...

So here's what I had to do - in the right order to get things working. Not bad, but it's basically the instructions for a dump/load, so I'll assume we know this going in.

First, create a complete dump of the database. Assuming that all these things are installed on Mac OS X, and using Homebrew, the paths are not important - they are all fixed with Homebrew, anyway.

  $ pg_dumpall > dump_file

Next, shut down the running server, update Homebrew, and then upgrade postgres within Homebrew. Just to be safe, let's re-link the launchctl file because in this case, it has changed, and better safe than sorry.

  $ launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
 
  $ brew update
 
  $ brew upgrade postgresql
  $ ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents

At this point I need to move the old database data to the side, and then initialize the database with the new codebase. Once that's done, we can then restart it with the re-linked launchctl file.

  $ cd /usr/local/var
  $ mv postgres postgres.old
 
  $ initdb -D /usr/local/var/postgres
 
  $ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

Finally, we need to load up the entire database from the dump file we made in the first step.

  $ psql -d postgres -f /path/to/dump_file

Check and make sure that everything looks OK and then you can easily remove the old database directory:

  $ rm -rf /usr/local/var/postgres.old

That's it.

Keep Going… Just Keep Going… and Try to Do Good

Monday, April 20th, 2015

Path

These last few weeks have been up and down, and I feel certain that it's going to get a lot worse before it gets any better. My back set me back - a herniated disc - nothing you can help, I do all the stretching and exercises, it's just life. But I was down for a few days last week. I'm on the mend, thanks to this not being the first time it's happened, and in a few weeks I am sure I'll be better. But it's a blow...

I also had a run-in with family this past weekend and while I love to see them, I know that they stiller unhappy with me - kids of divorce are something I'm very familiar with. It is what happens... sides are chosen... blame is assigned... it is what it is, but it also hurts. Again, in a few weeks, this will all be a memory, and things will seem to be back to "normal".

It's really just giving things time to become The Past. I've heard that over and over again in the last few years, and every time I hear it I'm hurt that it's the only thing anyone seems to say, but then 6 months later, I realize that it's the only thing they could say. It's an honest assessment of what happens when people get hurt.

Bones need time to heal. Discs need time to stop swelling. And the heart needs time to let things go. There's no pill to heal a bone... and while the prescription to reduce the swelling on my disc is really useful, I know that given time, it would go down on it's own. It'd just take a lot longer. And when people hurt each other, no words are going to shorten the time it takes to get past it.

I just need to keep going... get up in the morning. Try to do some good in the day. Have a good, healthful, lunch. Walk like you mean it. Get involved in your work, in your life. These don't really make anything better - they just make it a lot easier to pass the time. That's what really needs to happen. But these make the time seem to pass faster.

I just have to keep at it.

Adium 1.5.11b2r5922 is Out

Monday, April 20th, 2015

Adium.jpg

This morning I checked on Adium, and thankfully, the maintainers have released a new build - 5922, which is fixing some things I'm sure are important, but the big thing I'm looking for (most likely in vain) is connectivity to Hotmail IM again. It's now being called MSN Live, and even that is supposedly going away in favor of Skype - also owned by Microsoft.

And I'm told that the libpurple changes for Hotmail IM are in and are related to a usage key - like so many authentication schemes are, but that the Adium guys haven't updated the code to use the latest libpurple and until they do, it's going to be dead.

Maybe this doesn't matter... Microsoft bought Hotmail and Skype, and they are free to shut down whatever they way - it's their property now, and it's all up to them. It's just sad that they bought it for it's visibility in the market, and then they let it deteriorate to the point that it's name is trashed, and then they can drop it. It's kinda predatory, if you think about it... but no one forced Hotmail to take the money. It's just business.

Anyway... I'm hoping it gets fixed, or that a really great IM tool comes up. If not, I'll have to get the code and figure it out on my own as I really like this tool.

Interesting Tweet about Ruby Development

Thursday, April 16th, 2015

This morning an old co-worker of mine retweeted this very interesting tweet about Ruby development:

It's true, and I think it's one of the reasons I liked moving from C++ to Ruby - the OO was familiar, and the tools and Convention over Configuration made it nice and easy to get things done - and fast.

But then the reality set in. It was always going to be like this. That's when I realized I don't like big cities. Clojure is the way I think with writing code now, and it's the cleanest way I know to write with simplicity.

Acknowledge truth when you hear it. Amen.

Interesting Problem with Google AdWords API

Wednesday, April 15th, 2015

AdWords

I was working on stripping out a little bit of code from a project at The Shop today, and when I stripped out the library I had made, I got the following error when trying to start the REPL:

  $ lein repl
  Exception in thread "main" java.lang.NoClassDefFoundError:
  clojure/tools/logging/impl/LoggerFactory, compiling:
  (/private/var/folders/ct/jhkds06j26v1lq2t40jx4cndl_629q/T/
  form-init4416651774354867948.clj:1:124)
      at clojure.lang.Compiler.load(Compiler.java:7142)
      at clojure.lang.Compiler.loadFile(Compiler.java:7086)
      at clojure.main$load_script.invoke(main.clj:274)
      at clojure.main$init_opt.invoke(main.clj:279)
      at clojure.main$initialize.invoke(main.clj:307)
      at clojure.main$null_opt.invoke(main.clj:342)
      at clojure.main$main.doInvoke(main.clj:420)

And if I put the library in the project.clj, I don't get this error, but if I take it out, I get this error. And I needed to take it out.

When I did a lien reps :tree to see what overlaps there might be in the libraries, I found a few in the Google AdWords libraries. Easily enough, I took them out, and forced the right version with a simple:

  ;; AdWords Java API
  [commons-lang "2.6"]
  [com.google.api-ads/ads-lib "1.38.0" :exclusions [commons-lang
                                                    org.slf4j/slf4j-api]]
  [com.google.api-ads/adwords-axis "1.38.0" :exclusions [commons-lang
                                                         org.slf4j/slf4j-api]]

because the conflict was in the Google jars and both 2.5 and 2.6 of commons-lang were being used. Simply exclude them both, reference 2.6 first, and that should take care of it.

But it didn't.

So I took to the Google and found that someone had solved this by putting the class in the :apt section of the project.clj file. So with that, I tried:

  :aot [clojure.tools.logging.impl bartender.main]

and then things started working just fine again.

I'm guessing that by building the uberjar for the other library, it did this compilation, so that it wasn't necessary for this project. Take it out, and we have a problem. Force the compile first, and it's all good.

Glad I figured that out.