Promises and lie.js v1.1.2

I have just published v1.1.2 of lie.js

The library now uses more fluent names and matches the default used for timeouts in Javascript.

This is now being built and published to npm using CircleCI. The minimal test dependencies are kept upto date using dependabot.

Thanks to @ll782 for suggesting improvements.

The point of the library is to introduce timeouts into javascript Promises. It’s only by making timeouts explicit can you build a reliable application. Currently it allows rejects and success with a default value.

I plan to add typescript declarations to the project.

Javascript Promises and Lie.js

I have just published my first open source npm package, lie.js.

yarn add lie.js

It provides two useful functions creating a Promise that times out with a given error and another that will succeed with a default after a timeout.

The practical use of these is that you can use them with Promise.race to create functions with a bounded response time. It makes it easier to keep within a time budget if you can say go get a value or return a default if too slow.

Developers Toolbox

A developers toolbox should include:

  1. A Statically typed language
  2. A Dynamically typed language
  3. A scripting language

This can be less that 3 different languages.

You also need to know when to use each of them.

Currently my go-tos are:

  1. Groovy

2. Elixir

3. Bash or Powershell

Groovy is a halfway house. You can use @CompileStatic to enforce the parts that you want. It has enough types to allow Intellij to perform essential refactorings.

Elixir is a concurrency-oriented language that is dynamically typed and functional.

Bash is great for glueing together small unix utilities. You can get a long way using sed, awk, grep, jq and curl.

For interactive investigation of systems there is always the powershell REPL.

Working with Hub

Hub is a cli for github.

I mostly use it for creating pull-requests or to navigate to the github page for the current repository.

It can be used for more, including calling github api’s

Here is an example of fetching a file from a repo (which would work based upon the credentials attached to hub).

hub api -X GET /repos/chriseyre2000/sample-readme/contents/README.md -H "Accept: application/vnd.github.VERSION.raw"

This fetches the content of the file.

Intend to use this to analyse the package.json of a range of projects.

These will be passed into https://github.com/chriseyre2000/package_compare so that I can load a neo4j database. This will allow me to analyse the package dependencies.

Microservices can result in a lot of packages ….

This is a script that can be used to load a node package.json from github into a local neo4j database:

#/bin/bash
owner=$1
project=$2

hub api -X GET /repos/$owner/$project/contents/package.json -H "Accept: application/vnd.github.VERSION.raw" > $project.json
package_compare $project.json localhost neo4j magicbeans

Metaprogramming Elixir – Part One

This is a work through an discussion of Metaprogramming Elixir.

The entry point of metaprogramming in Elixir is the quite macro.

quote do: 1 + 2
{:+, [context: Elixir, import: Kernel], [1, 2]}

This allows the transformation of a code block into the abstract syntax tree (AST). This can then be manipulated like any other data structure and return to the generated code. The practical upshot of this is that half of the Elixir language is actually macros. You can if you need to write your own macros to perform complex operations simply.

There are recommendations to limit the use of macros to things that you can’t solve with normal functions. It’s possible with macros to create a powerful equivalent of inheritance, but must be used sparingly to avoid magical code.

Most of this work takes place at compile time rather than at runtime.

You use require to import macros.

General warning: in languages that have implicit returns adding logging at the end of a function masks the result. Capture the result, log then return result.

unquote is a technique where a macro can read variables from the hosts context. This is how you pass parameters into a macro.

Simple Promises In Javascript

This is how to wrap a callback api in promises:

// Sample function with callback
function clientFactory() {
  return {
    request: (name, callback) => {
      callback(name)
    }
  }
}

let client = clientFactory()

client.request('a', console.log)

// Wrapping a callback into a promise

function returnCallbackResult(input) {
  let promise = new Promise(
    resolver => {
      let client = clientFactory()
      client.request(input, (a) => {
        resolver(a)
      })
  })
  return promise
}

returnCallbackResult('b').then( console.log )

// How to wrap a promise

function chainingPromise(input) {
  let promise = new Promise(
    resolver => {
      input.then( (a) => resolver(`wrapping ${a}`))
    }
  )
  return promise
}

chainingPromise( returnCallbackResult( 'c' ) ).then(console.log)

Designing Elixir Systems With OTP – Part Seven

I have finally finished working through the example in the book.

https://github.com/chriseyre2000/mastery ( 94529b1)

This is a great introduction to OTP covering some details that I have not seen elsewhere. In particular the ability to import an OTP project and not have it auto start will be useful elsewhere.

The last few chapters do seem rushed, and the example code does not quite match what you get when it is typed in. However it is a great example of building a domain model in Elixir and then adding on the external links later. This would count as Hexagonal Architecture.

This is more of a training course that a book. You would have trouble simply reading through without working on the exercise. This does take a significant amount of time.

Designing Elixir Systems With OTP – Part Six

We are now onto writing the outside in tests.

I have got as far as the first test. This is failing with authentication errors.

[error] Postgrex.Protocol (#PID<0.251.0>) failed to connect: ** (Postgrex.Error) FATAL 28P01 (invalid_password) password authentication failed for user "chris*****"

iex -S mix came to the rescue here:

h Ecto.Adapters.SQL.Sandbox.checkout

Checks a connection out for the given repo.

The process calling checkout/2 will own the connection until it calls checkin/2
or until it crashes when then the connection will be automatically reclaimed by
the pool. 

## Options

  • :sandbox - when true the connection is wrapped in a transaction.
    Defaults to true.
  • :isolation - set the query to the given isolation level.
  • :ownership_timeout - limits how long the connection can be owned.
    Defaults to the value in your repo config in config/config.exs (or
    preferably in config/test.exs), or 60000 ms if not set. The timeout exists
    for sanity checking purposes, to ensure there is no connection leakage, and
    can be bumped whenever necessary.

This was the important clue that I had not got my test database configured correctly.

This is the new version of config/test.exs

use Mix.Config

config :mastery_persistence, MasteryPersistence.Repo, 
                             database: "mastery_test", 
                             hostname: "localhost", 
                             port: 54320, 
                             pool: Ecto.Adapters.SQL.Sandbox,
                             username: "postgres",
                             password: "postgres"

config :mastery, :persistence_fn, &Mastery.Persistence.record_response/2

I had “forgotten” the username here.

I now have the persistence tests implemented: https://github.com:chriseyre2000/mastery (dc6c5bf)