Developing on Staxmanade

Easily simulate slow async calls using JavaScript async/await

(Comments)

Recently I wanted to manually and visually test some U.I. that I couldn't easily see because an async operations was happening two fast. (first world problems)

I've really been enjoying the new async/await syntax that can be leveraged in recent JavaScript transpires such as Babel and TypeScript but when it happens so fast on a local development environment, some U.I. interactions could get tough to test out. So how can we slow this down or more appropriately add some stall time?

As an example, let's say you have the following async javascript method


var doSomething = async () => {
  var data = await someRemoteOperation();
  await doSomethingElse(data);
}

If the first or second asynchronous methods in the example above were running too fast (as were in my case), I was pleased to see how easy it was to inject a bit of code to manually stall the operation.

The snippet below is short and sweet... this just delays continuous execution of an async operation for 3 seconds.

  await new Promise(resolve => setTimeout(resolve, 3000));

The little baby staller helper

Give it a name and make it a bit more re-usable.

async function stall(stallTime = 3000) => {
  await new Promise(resolve => setTimeout(resolve, stallTime));
}

The above helper can be used by just awaiting it (see below)


var doSomething = async () => {

  var data = await someRemoteOperation();

  await stall(); // stalls for the default 3 seconds
  await stall(500); // stalls for 1/2 a second

  await doSomethingElse(data);

}

Now we have an async function that runs slower - isn't that what you always wanted?

Happy Stalling!

(Comments)

One Programmers Letter to his Wife

(Comments)

One of my core natures is as a builder and creator. I'm strongly introverted so much of my time is spent in my own head. My best and sometimes worst times are regularly spent by myself. I know you already know many things about introverts, but as a refresher I'd like you to read this.

Caring for your introvert

As a creator, one of the happiest moments we can experience is getting into a state of "flow".

In positive psychology, flow, also known as the zone, is the mental state of operation in which a person performing an activity is fully immersed in a feeling of energized focus, full involvement, and enjoyment in the process of the activity. https://en.wikipedia.org/wiki/Flow_(psychology)

I've heard this flow state described as a process where the mind is so focus on the task at hand, so engulfed in the spirit of the process that all other external processing of our environment and even our own bodily needs can be ignored. The brain puts so much energy and focus into this, that things like the need to eat, sleep, or sometimes even ignoring the restroom (for as long as possible - waiting until my bladder is SCREAMING at me).

I'm quite happy when I'm making progress on my creation(s) as they can often invoke this flow state. While the opposite of the "enjoyment" can certainly happen while working on projects as they can frustrate the heck out of me sometimes and if it ever bleeds into our relationship I'm sorry for that.

I wish I could convey the highs I can experience while in "flow" as strongly as you've likely see my frustrations about the lows. Sadly, without the lows, struggle, up hill battles, cussing at the computer I could possibly never really experience the feelings of success or overcoming that struggle and enjoy them as much as I do.

Between work, family time, children, shopping, housework, sleep and whatever else we fill our days with, it often times feels like I get to apply very little time to this thing that I am truly driven (maybe slightly addicted to) and excited about.

I know you try to give me time to work on these things. There are times you think you've given a Saturday morning or an evening for me to work on my thing. However, sadly for it to truly be a successful session, I need time and space with room to concentrate. An hour before bedtime makes me feel like I shouldn't even try, because it could take at least 30-40 min to get back into the project leaving so little time to be productive that it's not even worth starting. These are times when I decide to blow any amount of time I've been given and just waste it watching a show on Netflix. Not because I don't want to work on my thing, but because I know the amount of effort it will take to get into the flow state will take far too long to make it worth it. If I were to get into flow, I'm then going to want to stay there and likely push past my bed time (which is getting harder and harder to recover from).

I don't want this to sound like this creation/building thing is more important than my family. In fact it's not. If you look at my actions and track record, the amount of time I have pushed aside so I could help you with your endeavors by watching kids, taking on extra shopping trips, house duties as well as the financial obligation (and strain), and still finding time to spend with you in the evenings at the expense of this thing I want to do should prove that my commitment to the family (and you) is still a priority.

I don't know how to close this out an wrap it up, other than to say I love you. I love my children. I also love what I build. I would like to work with you to find a way to balance these items a little better.

(Comments)

Reusable React Component with Overridable Inline CSS Styles

(Comments)

React's Component model is great at allowing the component creator to define the interface that consumers of the component interact with. (What is exposed vs what is abstracted away).

If you're building a component and using any in-line styles and you're not careful you can lock the consumer of you're component out of potential customizations they may require for their specific use-case (that you can't think of or foresee). Trying to build components to be reusable and a little more OCP can be challenging especially with how difficult it can be to get css layouts the way you (or the consumer of you're component) may want...

As an example, let's create simple img component to illustrate the point.

Let's say we have the following image component.

import React from 'react';

export default class Image extends React.Component {

  render() {
    return (
      <div>
        <img src={this.props.src} />
      </div>
    );
  }

}

The above component is very simple and very specific.

Now let's say we allow our consumers to customize the height or width of the image. You may think, ok, simple we'll just allow the consumer to specify height and width as props to the component.

So the consumer could just go <Image height="20" width="20" src="someimage.png" />.

And you end up with something that could look like this.

import React from 'react';

export default class Image extends React.Component {

  render() {
    let imageStyle = {
      height: this.props.height,
      width: this.props.width
    };
    return (
      <div>
        <img src={this.props.src} style={imageStyle} />
      </div>
    );
  }
}

Now this works for a while, the consumers of you're component are happy they can control the height and width and everyone's humming along merrily.

Then someone comes to you and says they are having some layout issues and need to control something like float, or margin, or padding... This idea of extending the component with more props could become cumbersome if we have to do this for each and every potential layout option available.

How could we extend this generic pattern into something that allows the component to define a general set of happy defaults, while still giving the consumer complete control over layout?

One Possible Solution

We can use something like Object.assign() to easily accomplish this.

We can allow the consumers to pass in their own style={...} property and provide a set of sensible defaults for the component, but allow the consumer of our component to completely override a style if necessaryl

We can update our:

    let imageStyle = {
      height: this.props.height,
      width: this.props.width
    };

to the following pattern:

    let imageStyle = Object.assign(
      {},                               // target (starting with)
      { ...sensible defaults... },  // some pre-defined default React inline-style for the component
      this.props.style              // allow consumers to override properties
    );

Now if the consumer calls the component with <Image style={{height: "21px", width: "21px"}} src="someImage.png" /> the component's consumers' values will override any defaults provided. And they can extend the style with anything else they may need.

Happy Componentization!

(Comments)

Strange error on docker-compose up: oci runtime error: exec format error

(Comments)

I ran into a non-intuitive error while mucking around with docker-compose recently on an example.

docker-compose up

Building some_server
Step 1 : FROM alpine
 ---> 13e1761bf172
Step 2 : ENV DEMO_VAR WAT
 ---> Using cache
 ---> 378dbaa4a048
Step 3 : COPY docker-entrypoint.sh /
 ---> e5962cef9382
Removing intermediate container 43fa24c31444
Step 4 : ENTRYPOINT /docker-entrypoint.sh
 ---> Running in 5a2e19bf7a45
 ---> 331d2648d969
Removing intermediate container 5a2e19bf7a45
Successfully built 331d2648d969
Recreating exampleworkingdockercomposeenvironmentvars_some_server_1

The Error

ERROR: for some_server  rpc error: code = 2 desc = "oci runtime error: exec format error"
Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "compose/cli/main.py", line 63, in main
AttributeError: 'ProjectError' object has no attribute 'msg'
docker-compose returned -1

The Actual Problem and Solution:

I had a Dockerfile that used an entrypoint that looked like ENTRYPOINT ["/docker-entrypoint.sh"].

The real problem was the docker-entrypoint.sh script was missing a #shebang.

So changing this

echo "ENV Var Passed in: $DEMO_VAR"

to this

#!/bin/sh
echo "ENV Var Passed in: $DEMO_VAR"

solved my issue!

Also note it'll depend on the base image FROM <some linux distro> that may chagne what you're required #shebang should be.

Whew!

(Comments)

How to Get Environment Variables Passed Through docker-compose to the Containers

(Comments)

I've been playing with a little toy that uses docker-compose to bring together a web app, couchdb, and redis container into an easy-ier-ish cohesive unit.

While working on it (and to make it a bit more generic), my next step was to find a way to pass the database admin user/pass (and other configuraiton options) into the containers as environment variables which took me way longer to figure out than it should have...

Hopefully this posts helps it click for you a little faster than it (didn't) for me :)

If you land here, you've likely already poured over the different parts of documentation for docker, docker-compose and environment variables.

Things like:

In case things drift in the product or docs, this post was written using docker-compose version 1.7.1, build 0a9ab35 so keep that in mind...

I think the difficult thing for me was piecing the various ways you can get environment variables defined and the necessary mapping required within the docker-compose file.

Environment Variable Setup Stages.

For me it didn't click until I was able to think about the stages that needed to exist for an environment variable to go from the development computer -> to the -> docker container.

For now I'm thinking of using the following model...


 ------------------------       --------------------       ------------------
|   Env Source           |     | docker-compose.yml |     | Docker Container |
|                        |     |                    |     |                  |
|   A) .env file         | --> | map env vars using | --> | echo $DEMO_VAR   |
|   B) run-time terminal |     | enterpolation      |     |                  |
|       env var          |     | in this file.      |     |                  |
 ------------------------      ---------------------       ------------------

A working example.

If you want to see all of this in one place check out this github example which is outline below.

The example above is layed out like so...

.
|____.env
|____docker-compose.yml
|____env-file-test
| |____docker-entrypoint.sh
| |____Dockerfile
|____README.md

The .env file:

This is where you can place each of the environment variables you need in here.

DEMO_VAR=Test value from .env file!

As the docs say you can use # as comments and blank lines in the file - all other lines must be in the format of ENV_VAR=ENV_VALUE.

warning environment variables in you're terminal's context will take presedent over the values in the .env file. warning

The docker-compose.yml:

version: "2"
services:
  some_server:
    build: ./env-file-test
    environment:
     - DEMO_VAR=${DEMO_VAR}

The above file is the part where I got tripped up, and once I added the environment: section it all clicked.

You likely don't want every one of you're development or production server's environment variables to show up inside you're container. This file acts a bit like the docker run -e ENV_VAR=FOO option and allows you to select specific environment variables that are to be passed into the container.

I like the declaritive approach of this file as it makes environment variable dependencies explicit.

The env-file-test/Dockerfile:

FROM alpine

ENV DEMO_VAR WAT

COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

Pretty standard Dockerfile, but one thing I learned is you can setup default environment variables using the docker ENV directive. But these will be overriden by the .env file or variables in you're terminal's environment.

The env-file-test/docker-entrypoint.sh

#!/bin/sh
echo "ENV Var Passed in: $DEMO_VAR"

This was just a sample script to print out the environment variable.

Some other things I learned

warning The docs say you can specify you're own env-file or even multiple files, however I could not get that working. It always wanted to choose the .env file.

warning Also note: that if you have an environment variable specified in you're terminal that also exists in your're .env file the terminal's environment takes presedence over the .env file. warning

Happy Environment Setup!

(Comments)

Configuring Git to Use Different Name and Email Depending on Folder Context

(Comments)

Thought I'd share how I'm configuring user.name and user.email for git on my work computer. This is really just a post so when I forget how I did in the future I can google my own blog and be reminded...

I have always struggled with accidentally committing to an OSS project my work name/email or visa-versa, committing to a work git repo with my personal name/email.

For most, user.name shouldn't change, unless you're company ties your user.name to something specific to the company like a username. (Contrast: user.name = Jason Jarrett and user.name = jjarrett).

When I clone projects I always clone them into a folder structure that looks like

|____~/code
| |____personal/  <--- this is where I would put some OSS projects that I may be working on or contributing to.
| |____work/      <--- obviously work code goes in here

Thanks to this post where I learned about direnv and followed the last option I basically used these steps...

Setup

  1. Install direnv - brew install direnv (What about Windows? see this github issue and help make it work)

  2. Create .envrc file for each profile needing to be setup with the following content

    export GIT_AUTHOR_EMAIL=<your email>
    export GIT_AUTHOR_NAME=<your name>
    export GIT_COMMITTER_EMAIL=<your email>
    export GIT_COMMITTER_NAME=<your name>
    
  3. After installing and setting the .envrc files direnv will prompt to use the env file which we accept by running direnv allow.

Now I should have the following structure

|____~/code
| |____personal/
|    |____.envrc   <-- env settings with personal git user/email
| |____work/
|    |____.envrc   <-- env settings with work git user/email

What did this do?

Each time we cd into either a personal/ or work/ folder direnv will setup our shell with environment variables contained in that folder's .envrc file. This will then allow Git which respects these env vars and now we don't have to think about committing the wrong name/email to the wrong Git repositories.

Happy Gitting!

(Comments)

How NOT to Start Asynchronous Communication

(Comments)

 

Hey!

 

Don't you hate it when...

...someone is using a beautifully designed asynchronous tool to communicate with you but instead they try to pretend it is synchronous?

Please!!! If you ever have to communicate with someone through an asynchronous-able tool like a text message, instant messaging, or email don't just say Hey! and wait for a response.

Try saying Hey! I wonder if you could... or some alternative where the single message can contain both a polite introduction Hey along with some actionable context about why the polite introduction has taken place. If you can't begin to privde the initial context and are waiting for the other person to respond with Hey, you've both wasted their time and yours.

Often times a single chat message can distract someone who is concentrating hard on a subject. If a hollow Hey! is provided, you've likely pulled whoever you wanted to talk to out of that concetration as well as not provide them enough context to be abel to respond or help you. Instead they're possibly sitting there waiting for you to say something next, or maybe you're waiting for them to say Hey back (which you may never get)...

Asynchronous communication can be an amazing productivity tool if used efficiently.

Happy Chatting!

(Comments)

Easily Convert CSS to React Inline Styles

(Comments)

TL;DR

Click the logo to jump the tool...

The More Info Stuff

So you're working on a React app. It's up and running in you're favorite browser but you notice an issue with some layout. You think, ok, this should be easy to fix. You open up the developer tools, hack on some CSS within the browser till you get it looking just the way you want it to. Maybe it's several CSS properties you added or tweaked so you copy each of them into the clipboard so you can transfer them back to your application.

Then you realize, these styles aren't coming from a CSS style sheet, they're in-line styles right in you're React component.

Now you're like, FINE, I'll manually translate this to React-style-inline-CSS. This is no biggie if you do it once in a while. Except that time when you missed removing a dash or mis-cased a letter or maybe you forgot a JSON comma, or left a CSS semicolon. Never happened to you? Oh, you are so amazing if only I was as super cool as you. For myself and probably another 1 or 2 of you out there these problems do come up, but don't have to.

I hacked together a little tool that automates this translation. Allows you to paste you're CSS into a textarea, it translates to React inline style JSON CSS and you can copy it out while avoiding translation bugs.

You can see the project here: CssToReact If you have a suggestion or want to pull-request it your self you can check it out here: Source to Project

Aside: This should really be a plugin to my text editor where we can right click and say "Paste as React Style" instead, but for now it's a single simple little web page that will automate the translation for you. (I haven't looked for the plugin - if it exists or ever is created let me know in the comments...)

Happy CSS Conversions!

(Comments)

Slightly modified “CD” Command for Powershell: Now with dot.dot.dot.dot...

(Comments)

A while back I wrote about a replacement for the cd command on powershell that I wrote which provides some fun features such as history tracking, support cd'ing to a folder when a file path is given, etc... It's been a while since I've touched this helpful little tool which sometimes I even forget I wrote it because it's something that's used practically every day and "it just works".

For more information, check out the older posts about it here Slightly modified “CD” Command for Powershell and here: More than slightly modified “CD” command for PowerShell.

It now supports cd ...

Well, today I threw a quick feature into this utility that I've become accustomed to using in zsh on my Mac.

On many *nix command prompts you can type something like cd ..... This command translates indo cd ..; cd ..; cd .. (but executed as one command). The first .. counts as one directory and then each ane every . after that counts as another directory up the tree.

So now within PowerShell when I cd down into a deep folder structure, I can now use cd ....... to go back up N folders.

NOICE!

Happy CD'ing!

(Comments)

Oops - how a simple bit of automation put NuGet services on edge...

(Comments)

This past week I received an email from Microsoft's NuGet team asking if I could look into a bit of an issue with DefinitelyTyped's NuGet package publishing.

Some Background

A really long time ago, I wanted to access DefinitelyTyped packages within Visual Studio via the NuGet package manager. So I quickly wrote up a powershell script to accomplish this. This script has run almost continuously ever since, and primarily without issue.

There's been a couple tweaks/issues along the way - as to be expected, but it's been primarily hands-off.

As of today, these NuGet packages have been downloaded over 5,268,852 times - wow.

What does the automation do?

All of the NuGet packages generated for DefinitelyTyped are run through a build process on the good servers at AppVeyor (Thanks AppVeyor).

Every 2 hours the task does some git-fu to figure out what DT packages have updated (since the last run) and publishes updated NuGet packages for each updated DT package.

The initial problem report:

First let me say that thanks to Yishai and Maarten from Microsoft who brought the issue to my attention and were extremely polite and patient with the raised issue. So thank you, thank you, thank you for the support and being so friendly while working through this...

service status image of problem with nuget

Looking at status.nuget.org

It was pretty easy to see that every 2 hours a large spike in uploads to NuGet was happening.

service status image of problem with nuget

service status image of problem with nuget

While I can't say for certain this incident report on the status page was due to the NuGet automation, it was around the same time the automation was pushing extra builds (and right before I was contacted by Microsoft).

Was that my automation oops?

I didn't recall getting an error email from AppVeyor so I was initially suspicious. But logging in and looking at build history: hmmm. Looking back at my email, looks like I did receive the first failed build email - but must have been busy day as I didn't happen to notice that one email (when I usually do from other projects).

service status image of problem with nuget

YIKES!... so I quickly responded to Microsoft saying I'd shut down the automated portion and dig into it.

The Problem & Resolution

Turns out the problem was due to a large pull request that updated about every package in the DT repo. This meant it had to publish every single package, but for some reason (not showing in the logs) the AppVeyor job was failing at the end and not saving the fact that the packages were being updated on NuGet...

I have a way to run the NuGet publish manually on a local machine so I pulled down the project and ran the complete build. This took quite a while (almost 3 hours) and eventually I discovered the problem.

At the end of the script is a git commit -m {msg} command. This is an important step as it records what has been updated/published. The problem was due to the large number of packages published, the {msg} was so big that it was throwing an error saying the command line command was too long to execute. Causing the system to not complete the cycle and end up re-publishing all nuget packages every 2 hours.

I was able to manually commit with a shorter message and it brought the system back to normal.

And below is NuGet status after the fix.

service status image of problem with nuget

Thanks NuGet!

Turns out the NuGet team put some time into optimizing the publishing process of their service - so maybe there was a benefit to this whole fiasco, but hopefully we won't be hammering the system going forward :)

So I'd like to say thanks again to the NuGet team for you're kind support email and professional way of handling the issue. This is a great example of how Microsoft is helping the OSS community and their support is really taking off and showing promise!

Also Good Point

service status image of problem with nuget

Happy NuGetting!

(Comments)