Living with Hybrid AngularJS/Angular Applications

AngularJS falls out of support at the end of this year. If you still have a sufficiently large AngularJS codebase then a full migration is not an option. There are third party companies that sell support for when the official support ends, if being supported is important.

The only viable option is to move to a Hybrid application mixing AngularJS with Angular. This involves the use of ng-downgrade and ng-upgrade to bridge the boundary between the two.

The first stage of this process is to get the Angular JS app upgraded to the latest version. This can be non-trivial if you have an old codebase.

Early versions of AngularJS used an older proposal for Promises that predates (and is incompatible with) the now standard Promises. This may require the team to learn the differences between old and new Promises.

Modern Angular libraries now use Observables. This is another technique to understand before migrating. Observables allow the consumption of data before it has been fully read. This typically allows pages of data to be consumed. However with an older codebase for the backend then this may not be very useful.

The new libraries assume that the data being supplied is JSON, rather than the XML that older applications used. Early AngularJS projects will probably have a Java backend based upon the technology recommendations of the time.

Angular is also typically written in Typescript rather than JavaScript. This is another learning curve for the development team.

Concurrent Data Processing In Elixir (B4) Part 2

Chapter 1 was about Tasks

Now working on Chapter 2

This implements a Job Control system (with retries) using a GenServer.

This builds a more complex setup for supervisor trees.

This introduces a DynamicSupervisor and then adds transitory supervisors that watch their own jobs (which can then terminate cleanly.

Here is the sample from chapter 2:

The important detail here is the use of a Registry, which exposes the underlying ETS (Erlang Term Storage) system used.

Concurrent Data Processing In Elixir (B4)

Now that the book has reached the sent to print stage I am again working through it.

Here is the repo containing the samples from the first chapter:

The first chapter works through the simplest solution to concurrency: Tasks.
It starts with a simple slow example and step by step adds more sophistication until you get to have a Task.Supervisor watching the code.

This is one of the more elegant examples of demoing the power and simplicity of Elixir tasks that I have seen.

Some Useful Aliases

I have started to add custom aliases to my bash setup to reduce typing time:

alias ism="iex -S mix"

This is great for turning code into an interactive session

alias mtp="mix test --include pending"

This allows quick testing of Elixir Exercism exercises.

Testing Your System As A Chain

A given software system is a series of components that need each other to work. To test it you can either test all of it or you can treat it like a chain and test each link.

The current system I work on has a database, a Java backend, JSP views and uses AngularJS in the front-end

In order to comprehensivly test it you need a range of components. Featupent re flags can be tested by asserting that the page has certain elements present or absent. You can test for the presence of a given angular tag.

The angular components can be tested in a unit test framework in isolation.

Protractor is useful for checking that the components hang together without errors. There are so many places that JavaScript can live that only by looking for errors on the logs or ensuring that the page still has interactivity can you be sure you have s functioning page.

I spent some of last year looking for these assertiobs in React only to find them in an angular library.

Using Livebook as a Model

I have been having a quick experiment with livebook.

This is an interactive website that can be used to easily share Elixir code.
Think of it as Juypter Notebooks but with the backing system being Elixir rather than Python.

It has a very neat docker image:

docker run -p 8080:8080 livebook/livebook

This will stand up a local website running livebook. The console will give you a link (including a token) to allow you to access it.

You can create notebooks and add sections in Markdown or Elixir.
The great thing is that these can be interactively edited by multiple concurrent users.
You can also export a notebook as a file, publish the details and import it into another livebook.

I have been thinking about using this to recreate an old mac simulation tool. This tool allowed you to build a model with data flowing through it and you could use it to see bottlenecks.

I have three code blocks:

The first is the initialisation block

Agent.start_link(fn -> 0 end, name: :complete)
Agent.start_link(fn -> 0 end, name: :iteration)
Agent.start_link(fn -> 0 end, name: :qa_backlog)

The second is the update block

Agent.update(:iteration, fn x -> x + 1 end)
Agent.update(:complete, fn x -> x + min(10, Agent.get(:qa_backlog, & &1)) end)
Agent.update(:qa_backlog, fn value -> max(value - 10, 0) end )
Agent.update(:qa_backlog, fn value -> value + 20 end)

The third is the output block

:ok = IO.puts "Iteration #{Agent.get(:iteration, & &1)} Backlog #{Agent.get(:qa_backlog, & &1)} Complete #{Agent.get(:complete, & &1)}"

If you put the three blocks into livebook then you have the start of a model.

This is a very simplistic model. It attempts to show that the QA team will never be able to keep up with the two dev teams feeding it work. This could become far more sophisticated (with a random percentage of QA items failing and being returned to the teams). The idea here is to show how you can use an Agent in livebook.

I am going to see if you can add visualisations.

Programming Phoenix LiveView – Part 1

I have now started work on the Phoenix LiveView Book.

Still early days on this book.

However this will make creating a phoenix app much easier:
docker run -d -e POSTGRES_PASSWORD=postgres -p 5432:5432 postgres:11

That makes a default password postgres image.
I would not recommend default passwords for anything other than local demo databases.
This makes setup much less painful.

Here is the repo that I am working on:

Patching AngularJS

2021 is a very unusual time to be returning to use AngularJS. This is the version of Angular that is going out of support at the end of this year! However I have a client that has a very large codebase that needs to be moved to the latest stable version before they start the move to a more modern Angular version.

A key feature of AngularJS is that it is built using a dependency injection framework. This means that it is possible to replace parts of the supplied libraries with alternative versions. For this codebase this can mean an older version of one of the system components. For example the $http component changed it’s call interface between 1.5.6 and 1.6.0. It would be great to move the entire codebase to the more standards compliant promise library, but this is just not feasible for the size of the codebase. There are thousands of uses of the old syntax.

This does allow us to take advantage of working on a library that has been abandoned – we know all of the changes that the later versions have made and also know what the replacement looks like. This gives us a chance to look at the direction we need to take the code before we migrate. This is not going to be quick.

Stop Fighting The Last War

There is a classic military problem at the start of a new campaign. The goals and missions initially attempted are based upon the doctorine that worked in the previous campaign. This can have disastrous effects. During the first Gulf War this resulted in a convoy of tanks left inoperable at the side of the road. A key filter needed to be replaced to allow use in a desert.

I am shortly to start on a new project at a new client in a very different domain to any that I have worked in before. This will involve checking all of the assumptions that I am about to make.

The previous engagement had poorly defined goals. This is one point that can be corrected early on for the next project. What is the problem we are trying to solve? How do we measure progress towards this goal? What are the constraints here?