Deploying With Ansistrano

I have a major problem. I keep waaay too many open tabs on my phone. Every time I see something interesting – via Twitter, Hacker News, or Reddit – I open the link in a tab and promise myself I will check it out more thoroughly soon.

I currently have 47 open tabs ūüôĀ

This is only amplified by the fact I do the same on desktop. Right now, across three desktops I have over a hundred open tabs.

It’s becoming an epidemic.

Anyway, once in a while, one of these tabs becomes useful.

Recently I hit on a problem whereby I needed to deploy a bunch of individual JavaScript files – node.js scripts – to a server to be used as Rabbit MQ workers.

I had a bunch of requirements for these workers:

  • start with specific flags ( --harmony-async-await¬†)
  • restart automatically if the server reboots
  • restart if the script crashes
  • can run multiple instances

And so on.

These turned out to be the superficial problems – and I say this because there’s a tool out there that already nails this problem – PM2.

Initially I thought these would be the hard problems.

What I hadn’t banked on was how much of a royal pain in the backside it might be to deploy my node.js scripts to dev / prod / wherever.

 

My requirements are fairly straightforward Рthey could be solved by using rsync. However,  rsync becomes unmanageable as a project grows.

There’s the issue of remembering the right command, and then duplicating the command – altering slightly – for the prod deploy.

And what if it goes wrong? Well, you have to handle that yourself.

Call me spoiled, but having become accustomed to Deployer (Matt did a fantastic job on this course btw, you should check it out), I now use that as my baseline for deployments.

I have a similar tool I use on JavaScript projects called Flightplan. It offers a decent level of functionality, but with one major issue (from my p.o.v):

It is a pain to deploy more than one directory.

Flightplan works on the assumption Рas best I can tell Рthat you will be running your project through some webpack-style setup first, producing a dist directory which contains everything you need to boot your single page app, or whatever.

This is cool, but I needed to run many different worker scripts – all ideally from one directory.

As best I understand it, webpack allows this via it’s multiple entry¬†options, but I’m not using webpack. Actually, I tried to use webpack but it threw out a bunch of errors right away and I gave up.

I also tried Deployer. But that didn’t work much good either. JS mixed with PHP leads to mess.

Enter Ansistrano

Ok, so all that was a very long-winded precursor to the eventual solution.

However, I felt I needed to do justice to how much I have struggled to get this thing working. It’s taken 5 hours… ouch.

Needless to say I tried to give up on getting Ansistrano at numerous times (see how I ended up at Deployer, Flightplan, webpack etc).

In the end though, I cracked it. So here goes:

Firstly, my playbook:

Pay special attention to the¬† ansistrano_git_repo¬†entry, whereby I needed to add the prefix of¬† ssh://¬†to make this work. If you don’t, you will find Ansible doesn’t understand the path you are providing, and blanks it out instead :/

I guess I wasn’t the only person to notice this.

Also, note that the typical git path given by gitlab will contains colons, which need to be replaced with spaces:

 

Now note, this is an Ansible issue, not an Ansistrano issue.

This should be enough to get most of the way there.

However, I hit upon another issue.

No matter what I did, all the Ansistrano managed folders were being created as root .

Since the days of yore, I have been using the same set of flags on my runs of  ansible-playbook, and today I was well and truly bitten on the backside:

Ultimately this command sees me through. I’ve started using -vvvv¬†on every playbook run as it saves me having to re-run when things inevitably go wrong. Also, for the love of God, use snapshots before running.

But yeah, my issue was I was running with the additional flag of  -s which forced the playbook to run as root. Silly me.

Anyway, early signs are promising. It all works. I just wish it hadn’t taken me so much time to figure out these problems. Hopefully though, by sharing I can save someone some hassle in future.

An issue with React Widgets DateTimePicker

When you have the fix to a problem, but don’t know the¬†root cause of why that problem is happening, you have two choices:

  1. Accept you have a solution, and move on, or;
  2. Accept you have a solution, and figure out the cause of the problem.

The problem is, #2 takes time. And that might not be time you have currently.

Dwelling on some problems is not the best use of my time in my current position.

So here’s my problem, and a solution, but I cannot offer you the root cause to this problem. Nor is it the defacto solution, I believe.

Using React Widgets DateTimePicker

I guess you’re either the kind of developer who creates everything themselves.

Or you first try using other people’s.

I wanted a Date Picker, ideally with time, and I would like it to be hooked up to Redux Form.

The good news, Redux Form already works nicely with React Widgets. See the previous link for a decent tutorial. And this code sample.

As a result, I can quite easily add in a Date Time Picker that’s hooked up to my Redux Store. This is good. It pleases me.

It also allows me to start laser focusing my A/B tests.

date-of-birth-as-a-timestamp
You’ve never A/B tested unless you know for sure customers don’t prefer timestamps.

But joviality aside (wait, that was humour?), I did hit a problem along the way:

react-widgets-calendar-size-issue
That’s not so good, Al.

There is a quick fix to this.

Add in a local (S)CSS style:

redux-form-datetime-picker-react-widgets
Better

It’s good, but it’s not quite right. Good enough for me to continue, though has been firmly lodged into the ticket queue under ‘improvement’.

Here’s what it should look like:

react-widgets-datetime-picker-proper

So there you go. Hope it helps someone. It’s unofficial. It’s not the real fix. Any pointers appreciated.

How I Fixed: uncaught at check call: argument [object Promise] is not a function

Earlier this month I started dabbling with Redux Sagas as an alternative to Redux Thunks.

At the time I was highly skeptical – largely around whether re-writing a significant portion of my JavaScript was good use of my time, given that I had no prior experience with generators, and that conceptually sagas sounded pretty hard.

But I kept hitting issues with Thunks. They just seemed so cumbersome, and error prone. I found writing tests for them to be painful, and adding in the Redux API Middleware made that even more complicated.

Ultimately, switching to Redux Saga has been one of the highlights of my current project. I love it. Every problem I have had so far has been made easier through the use of sagas.

But today I hit on a problem I haven’t seen before:

This is a generic version of the code I am using:

I have highlighted the problematic line.

The issue here is that the error in the browser is fairly cryptic. It took me digging into the source code to figure this one out.

But actually the issue is really simple to fix.

The highlighted line above should be :

I was calling my function myself, and then passing the promise on to the Saga… whoopsie daisy.

 

 

How I Fixed: unresolved variable or type await

Ok, super easy one here, but as a newbie to  async /  await this did catch me out.

Let’s pretend we have a function:

This will present an error in WebStorm, and Googling came up only with a bug report from 2015.

In my case, WebStorm would give two different error messages:

webstorm-async-await-expecting-newline-or-semicolon

orwebstorm-async-await-unresolved-variable-or-type-await

Ready to kick yourself?

This I tell you brother, you can’t have one without the other ūüôā

 

Using async / await with React

I’m currently toying with thunks vs Sagas.

The idea of re-writing a significant portion of my app’s API connectivity (from thunk, to saga) is not entirely thrilling. However, sagas do appear to be the better solution given what I currently know, and would choose them if starting again from scratch.

The gist of my problem is that thunks have added in a layer of complexity – but they work.

For any API call that should be authenticated, I need to catch the call using a middleware and then add the necessary token, and so on.

Combine this with Redux Form, however, and I am left with a bit of a head-scratcher. This middleware is generic. If certain calls fail, I need to map the response (containing error messages) to an object that Redux Form understands, then stopSubmit');">dispatch the [crayon-584c81b737b54060112295-i/] action.

Anyway, enough about my problem.

Before making the switch I found a potential solution that involves using  async /  await. Being a sucker for new and shiny, I wanted to get it into my project.

Simply trying to use  async /  await resulted in an error for me:

Boo.

To fix this, I needed to import the babel-polyfill. However, a thing I found out is that you can import this dependency once in one of your top level components, rather than per file.

For example, in my project I have an  App component which contains a container which all other components in the app render into.

I added the single line:

as the first line in the file, and now async /  await works just fine.

These other two files may help in setting up: