Kubernetes and Elixir

This is a series of articles that cover using Elixir in Kubernetes:

https://david-delassus.medium.com/elixir-and-kubernetes-a-love-story-721cc6a5c7d5

This uses the following github repo:

github.com/linkdd/elixir-k8s-love-story

The difference in this series from most others is that it covers building a Kubernetes setup assuning that you have a BEAM cluster rather than just a set of go applications that require elections.

The programming model for the BEAM is very different. The model is closer to an operating system than a single machine.

I have not yet worked through it, but will study it.

Here is another article on clustering on Kubernetes https://mbuffa.github.io/tips/20201022-elixir-clustering-on-kubernetes/

Elixir Test Output

Elixir has been designed taking inspiration from a number of other languages. This makes the developer experience to be one of the best available. This includes test runner support and the ever useful mix utility that hosts everything from project creation, dependency management, database migrations and repl support.

One feature that is slightly lagging is the test output support. Previously I had worked in Groovy using Gradle and Spock. The test output report was spectacular. You could generate a detailed report artifact, which was either a directory of html or a single zip file containg the same. This report would list all of the test suites with the ability to see the associated console output with the test. This becomes great to have in a CI setup as these can cheaply be stored in S3 which allows detailed investigation of historical failed test runs.

The following provides the hooks to improve the Elixir story. I have been considering writing one that produces a livebook as the output.

https://stackoverflow.com/q/41350135/662571

Here is a sample project that uses some of the above techniques:

https://github.com/chriseyre2000/my_custom_test_formatter

Currently the project will add the name of the current project before the summary line of tests passed and failed.
The idea being that an umbrella project could report which project it was. This can make life a bit easier when dealing with a build server that only shows a limited span around failures.

Warning this does not work in an umbrella project.

Thoughts on CQRS ES

The theory goes that an event sourced system has a perfect audit trail. However in practice this is only partially true.

It does have a complete history of all of the commands that have succeeded. It tells you nothing of the load on the read model and the failed commands. These require more detailed information that may reside in your observability system.

Helm

I am beginning to explore Helm now that I have access to a Kubernetes system.

Helm is the release manager for K8S. You use this to deploy “releases” to a Kubernetes envionment.

It’s amazing the amount of useful info that is returned.

helm get – returns the list of currently deployed releases.

You need helm get -a to include the ones that have failed to deploy.

helm get values <release name>

or

helm get manifest <release name>

reveal much of the details of the infrastructure.

I hope to turn this into a visualization.

Documenting CQRS ES

I have been looking for a decent template to document CQRS ES.
I think I have found one: https://github.com/tmorin/plantuml-libs

The following diagram:

This was generated using plantuml from the following source:

@startuml
' configures the library

' loads the library's bootstrap
!include https://raw.githubusercontent.com/tmorin/plantuml-libs/master/distribution/bootstrap.puml

!include https://raw.githubusercontent.com/tmorin/plantuml-libs/master/distribution/eventstorming/bootstrap.puml

' loads the package bootstrap

' include elements
include('eventstorming/Element/FacadeCommand')
include('eventstorming/Element/Command')
include('eventstorming/Element/Result')
include('eventstorming/Element/Event')
include('eventstorming/Element/DomainEvent')
include('eventstorming/Element/IntegrationEvent')
include('eventstorming/Element/Query')
include('eventstorming/Element/ReadModel')
include('eventstorming/Element/UserInterface')
include('eventstorming/Element/Aggregate')
include('eventstorming/Element/Service')
include('eventstorming/Element/Policy')
include('eventstorming/Element/Saga')
include('eventstorming/Element/Process')
include('eventstorming/Element/Timer')
include('eventstorming/Element/Person')
include('eventstorming/Element/System')
include('eventstorming/Element/Comment')

' display elements
FacadeCommand('FacadeCommand')
Command('Command')
Result('Result')
Event('Event')
DomainEvent('DomainEvent')
IntegrationEvent('IntegrationEvent')
Query('Query')
ReadModel('ReadModel')
UserInterface('UserInterface')
Aggregate('Aggregate')
Service('Service')
Policy('Policy')
Saga('Saga')
Process('Process')
Timer('Timer')
Person('Person')
System('System')
Comment('Comment')

@enduml

The advantage of this is that it does not require a local copy of the project.

The downside is that it requires an internet connection, and is at risk of the project being moved.
I can see myself making use of this.

I have forked this project so that I can have a guaranteed stable location and use a single file.

This reduces the above to:

@startuml

!include https://raw.githubusercontent.com/chriseyre2000/plantuml-libs/master/distribution/eventstorming/eventstorming.puml

' display elements
FacadeCommand('FacadeCommand')
Command('Command')
Result('Result')
Event('Event')
DomainEvent('DomainEvent')
IntegrationEvent('IntegrationEvent')
Query('Query')
ReadModel('ReadModel')
UserInterface('UserInterface')
Aggregate('Aggregate')
Service('Service')
Policy('Policy')
Saga('Saga')
Process('Process')
Timer('Timer')
Person('Person')
System('System')
Comment('Comment')

@enduml