Wednesday, February 15, 2017

Atomic UI / API Pattern



One of the main issues that UI Products face when it deals with a MicroService backend is the need to coordinate API calls and successfully commit all changes (when made by the user) in a Atomic level. It's tricky to do this as individual API calls can fail or be slow to respond and the UI might will probably maintain an interim Data State/Store (basically an object in memory) which then needs to be remapped to the API schema and saved over REST.

Let's look at an example:
  • Our UI Screen needs to render something (trigged by a Client side Route Change on the Single Page App - SPA)
  • The screen requires data from multiple MicroServices as the Screen is composed of different object elements, it makes multiple MicroService calls to gather all data needed to generate the Screen Content and Input Forms
  • User interacts with the data (adds something, edits something etc) - the UI App has to maintain these changes locally using an interim, browser based Data State/Store
  • User commits to publishing the data in the screen (which they have edited via a form) and "Saves" it. Business Logic in the UI needs to coordinate and remap the local Data State/Store to the various MicroService endpoints and SAVE/PUT

There are multiple failure points to this approach:
  • If the local Data State/Store is not handled with immutability then there will possibly be side-effects to that data (caused by bad coding)
  • On saving, some API calls may fail whilst some may succeed. This will cause a disconnect in the UI level as to what the server knows to be the correct data and what the UI believes to be the correct data (as the local UI will be bound to the interim data state)

One approach around this is to follow an atomic API -> UI relationship.

Where ONE Screen gets all it's content from ONE API and saves back to ONE API.


I'm not sure if there is a term that describes this pattern (if there is please correct me in the comments), but I'm calling this the Atomic UI/API Pattern.

This seems to be a common practice followed by the large UI Products in the world (Netflix, Facebook etc) using tools such as GraphGL.

I'll write more on this soon...

Friday, December 16, 2016

Apple Mac Webcam Camera not working? Here is a Quick Fix



I had to take a urgent video call today on my Mac and at the last moment found that my built in webcam was not working. In the browser, the video plugin to display the webcam feed was showing "Camera not found" and in other programs like Skype the video webcam feed was just showing a black screen.

Seems a restart would fix it (based on my reading online) but I had to fix it quicker and didn't want to restart the machine as I had some tasks running which I could not stop. I then found this below command which fixed it immediately. 

sudo killall VDCAssistant

Just open your "terminal" and type that and hit enter (you will have to enter your admin password).

Hopefully that will fix it for you too! 

Sunday, November 27, 2016

Beware - forever list vs sudo forever list are not the same

A few days back I noticed that my Pub/Sub Listener (a node.js script that listens for events and routes data to my Datastore) for Google Cloud Platform (GCP) was behaving badly. I had recently deployed some updated Listener logic which was being bypasses altogether.

My Pub/Sub Listener were "kept alive" using the Forever npm module, as I was working on a GCP Compute Engine, I was using sudo to run all my commands.

So I launched my Pub/Sub Listener using:
sudo forever app.js

To debug the issue, I ran the following to stop all my Forever scripts:
sudo forever stopall

And verified this by doing:
sudo forever list

It shows an empty list. So what was wrong? It seemed as be as though Forever was running some hidden processes and my Pub/Sub listener was still running.

After a bit of digging around, it seemed as though, sometime in the past I had launched my Pub/Sub Listener using
forever app.js

So what was the problem?

Well my scripts were running as both root user and my user permissions, and were essentially duplicated.

As you can see:



So to fix this, just stopall on your root account.
forever stopall

And make sure you only run your Forever script using the correct user permissions.

Happy Coding!


Thursday, June 30, 2016

Pushing a Dokku App from Multiple Computers and Fixing the "Could not read from remote repository" Error

I use Dokku to push the multiple Micro Services that power my blog www.wisdomtoinspire.com (which are hosted in a Digital Ocean server)

Dokku uses Docker and is a Free open source Heroku alternative which makes a Microservices architecture possible

Initially, I worked mostly on single computer which I used to set up Dokku on Digital Ocean and set my initial SSH keys etc

Recently I wanted to push a new Micro Service (which is deployed via Dokku on my digital Ocean machine) on a different computer but I ran into multiple issues.

  • I assumed that all I had to do was clone the GIT repo, set my Dokku remote (after creating a Dokku App on the server) and then pushing via "git push dokku master"
  • But I could not access the server. So I create a new SSH key with the same email I used previously when I set up the server and stored it in "id_rsa.pub"

I then SSHed into my Digital Ocean machine, and manually copied the new SSH into ~/.ssh/authorized_keys and then assumed I need to copy it into /home/dokku/.ssh/authorized_keys as Dokku might use it. I also switched to the "dokku" user (using "su dokku") and added the key to "~/.ssh/authorized_keys"

Assuming this would fix the issues I was having trying to push my app to the Dokku remote, I pushed via "git push dokku master"

And kept getting this error:
fatal: 'appname' does not appear to be a git repository
fatal: Could not read from remote repository.

I then dug around and came across these issue on Dokku's Github:
https://github.com/dokku/dokku/issues/1608 (Gitreceive doesn't work)

This comment struck out:
"Guess there was a bug in how you initially setup your keys. The dokku user is meant to be managed solely by sshcommand, and you aren't supposed to "ssh" in as that user, hence why things seemed to break for you."

Basically, it means that I should not try and add new SSH keys like the way I did. Instead I should remotely do it from my machine like it's mentioned in this article https://www.digitalocean.com/community/questions/dokku-add-new-ssh-key

i.e. I undid all those manual keys I manually copied in my Digital Ocean server and from my local computer I ran this:

cat /path/to/public_key | ssh root@yourdokkuinstance "sudo sshcommand acl-add dokku [description]"

Read more here (in the SSH command part)
http://off-the-stack.moorman.nu/2013-11-23-how-dokku-works.html

Now when you try "git push dokku master" it should start pushing your app to Digital Ocean using Dokku.

But I then ran into this issue:

 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'dokku@wisdomtoinspire.com:thumby'

:(

But I knew the above "pre-receive hook declined" usually appear when something goes wrong with the install and launch via npm. So I just enabled Dokku tracing like so "dokku trace off" (http://dokku.viewdocs.io/dokku/troubleshooting/) and fixed all my issues and my Service was good to go!

Hope this helps someone.

Happy Coding!


Wednesday, June 1, 2016

Undo/Reset last GIT Commit Locally and Remotely

If you are like me and you fork some project, make a bunch of changes and commit to your local and remote repositories only to discover that you pushed changes that should not go in.

Then here is a quick way to undo to a specific commit locally and then push that to the remote branch.


Keep in my mind that by doing this you will lose your local work (i.e. the work you want to undo) so only do this if you don't care about the work you did before you pushed the new commit.

First, find out the commit SHA you want to reset to. In Github you can get this like so:

Grab the SHA of the commit to want to go back to



In you command line run these commands one by one.
git reset --hard 0415b7a2bf2517f37f662e063ffee36706554d8f
git push --force

The reset syntax is basically:
git reset --hard target-commit-SHA (grab the full SHA by clicking the link in green above)


Your repos (local and remote) should now have gone back to the point you wanted it to.

Use at your own risk!! :)

Wednesday, May 18, 2016

Adding a "ref" to a Dynamically Inserted Child Component in React

I was working on a wizard type multi-step component for a React Application I was building (the component is called react-stepzilla in case you are interested in it)

It basically let's you throw a bunch of Child Components at it and it will take the user through those Components in a wizard type journey.

So basically it lets you build something like this.


Figure 1: react-stepzilla component look


The obvious use case for this would be to collect information from the user and validate that information as you go.

In this example, you initialise, declare and render the Component in your App (something) like this:

import Step1 from './Step1';

import Step2 from './Step2';

import StepZilla from 'react-stepzilla'

...

const steps =

    [

      {name: 'Welcome', component: <Step1 />},

      {name: 'Personals', component: <Step2 />},

      {name: 'Emergency', component: <Step3 />},

      {name: 'Medical', component: <Step4 />},

      {name: 'Review', component: <Step5 />}

    ]

...

render() {

    return (

        <div className='step-progress'>

            <StepZilla steps={steps}/>

         </div>

    )

}

and the outcome would look like figure 1.

As I was building this I hit a roadblock. Some of my Child "Step" Components (e.g. Step2) was a form that needed to be validated before we can move on to the next Step (Step3).

My Step2 Component exposed a public method called "isValidated()" which runs the entire form through validation and then returns a true/false indicator on validation state.

But Step2 was a Child Component to my StepZilla Parent Component and I didn't have access to any of it's methods via 'this.props.children' which is how I thought you should (I am fairly new to React I should add) but then I read that this is not possible (read https://facebook.github.io/react/tips/children-undefined.html)

I needed someway to reach into my Child Step2 Component and invoke isValidated() before continuing.

Upon further reading "refs" seemed to be the facility given by React to reach into Child Components (read https://facebook.github.io/react/docs/more-about-refs.html) and this seemed like the way I should do this.

But "refs" can only be declared to a Child Component in the render() method of the Parent Component. In the StepZilla Parent I was passing in a array of Child Components which was then injected into the Parent Component (something) like this:

import React, { Component, PropTypes } from 'react';


export default class StepZilla extends Component {

    ...

      _next() {

            // move to next step (if current step needs to be validated then do that first!)

            if (typeof this.refs.activeComponent.isValidated == 'undefined' ||

                this.refs.activeComponent.isValidated()) {

          

                    this._setNavState(this.state.compState + 1);

            }

      }

    ...

    render() {

        return (

            {this.props.steps[this.state.compState].component}

        )

    }

    ...

}

So I needed someway to intercept this injection and append a "ref" to the component so I can then reflect of it's validation state later on (in _next() method).

After much digging around I came up with a solution. Which is basically to clone the Child React Element and then append a "ref" to it. This was how I made it work.
export default class StepZilla extends Component {

    ...

    render() {

        const compToRender = React.cloneElement(this.props.steps[this.state.compState].component, {

            ref: 'activeComponent'

            }

        });

    return (

        {compToRender}

      )

    }

}

And this works in my situation!

A few notes relating to this design approach:
  1. Ideally in React you should not "reach into" Child and Parent Components as this goes back to a imperative modal of coding which React is trying to take us out of. But in some situations you cant avoid this. I did think of doing the above using "events" but it didn't make sense to me to overcomplicate this use case.
  2. I believe React.cloneElement does a "Shallow Clone" so it may have some adverse effects (which I still have not encountered but we cant rule it out)

Hope this helps.

Happy React Hacking!

Thursday, April 28, 2016

Using Webpack to Copy Static Files to your Build Folder

This article is relevant for: 
- node 5.8.0
- npm 3.7.3
it may or may not work for other versions.


I've recently started doing a lot of work with React and React Native. I created a React Native Starter kit  that uses webpack as the Module loader. I actually use Grunt and the "grunt-webpack" plugin but the build process uses webpack to bundle my distribution (production build).

I am fairly new to webpack so last week I hit a roadblock. I wanted to include a link to a "apple-touch-icon" static image on my app homepage so that a user can add a "shortcut" icon on their iOS device home screen. Basically I wanted to "Appify" my React App like so:

I wanted to reference this image in my homepage so that I can Appify my React App on iOS
If you have not done this before with your web apps, it's very easy to do. Basically you just create a link tag like so and put it on your homepage:

<link rel="apple-touch-icon" href="/assets/lifeletters-app-logo.png">

You will also need to add the following tags as well:

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

Like so:

I put this simple link tag to reference the iOS app icon image

So basically when I hit my "build" task webpack bundles all included resources (js, images, css etc) and puts it into a "dist" folder which I then deploy as my app build. But I needed webpack to pick up the "company-webapp-logo.png" and copy it to the "dist" folder as well so my "dist" folder looks like this:

I needed my "dist" folder to look like this

Unfortunately webpack only infers my JavaScript code and copies resources it finds there. I needed a way to copy "static"files over to my build folder as well. A task like this is veryeasy to do in a system like Grunt, but I wanted to stick to webpack as eventually I want to move away from Grunt.

I tried multiple webpack loaders like the webpack file loader but I could not get a simple copy to work. (with the file loader I managed to get the PNG image moved but the image got corrupted)

After more digging around I cam across the copy-webpack-plugin so I gave it a go.

And Bingo! I got the job done.

It's basically a very basic plugin to copy static file/folders to your build destination. Here is how you would configure it in your webpack config file.

Here is how you configure the copy-webpack-plugin plugin in your webpack config file

Initially I had my doubts that it would work as I was using the Grunt webpack module, but it still did.

I use webpack as part of a Grunt workflow like so...

This is a very basic workflow example but hopefully it will help some new starters to webpack.

If you have a better way to do it please let me know in the comments.

Happy Coding!

Fork me on GitHub