Edit me on Github

Blended ZIO #

About this project #

For now this is a personal project to learn about FP by migrating (rewriting) a real world application with an FP approach. I have decided to document the rewrite as much as possible, so others may benefit from the experience and to have a reference in case I want to ask questions on any of the FP related forums.

Even though it is my intent to complete the migration, paid projects might take precedence.

Refer to the individual modules to get more information about the module, its functions within Blended 3 and the migration status.

Heritage #

This project is based on Blended, an integration framework implemented on top of Scala 2.13, Akka, Akka Http and Akka Streams. It is currently in it’s 3rd productive generation.

The first generation of Blended has been implemented in Java and has used ActiveMQ, Karaf and Camel as core components. Once version 1 went into mainteance, we started to refactor the tests to Scala and with version 2 we decided to move to Scala entirely for all our self written components.

Also with version 2 we finished our integration test framework to automatically spin up our test environments in docker and use docker based integration tests.

With version 3 of the framework we have replaced Karaf with our own OSGi container framework written in Scala and all Camel based integration flows have been rewritten to Akka Streams.

For better orientation within the original project and the migrated modules here is an overview of the Blended use cases.

Moving forward #

Even though the code base of Blended is fairly robust and tested, there are some dark areas within the code base where nobody wants to go and much less make any changes. Having looked at several approaches how these areas can be addressed we feel that if there is a next version of the Blended framework it should be moving towards an FP implementation.

This is easier said than done, but nevertheless I have created the Blended ZIO project as a personal playground to achieve several things:

  • The code base of Blended 3 is not functional at all. It uses untyped actors under the covers which is one of the pain points when refactoring is required. The developer has to understand the interface in terms of which messages may be sent to the actors and which are the responses, but the type system and the compiler are of little to no help in understanding these interfaces. Blended ZIO on the other hand shall be as functional as possible.

    I have given some thought how to get from Blended 3 to Blended ZIO and have weighed refactor against rewrite. After going through quite a bit of documentation, asking on the forum etc. I am leaning towards a rewrite. This decision may swing into the other direction again, but even as I consider myself to be an experienced (Scala) developer I feel that refactoring towards to ZIO might require me to refactor modules which I am going to rewrite sooner or later anyway.

  • Blended 3 lives in a single repository and has grown to more than 60 modules within that repo. While that is convenient for refactoring on the global project level, the entire build process sometimes lacks flexibility. The latter has been addressed by moving the build to Mill, but still the build process feels somewhat complicated. With Blended ZIO, each module shall live in it’s own repository with it’s own release cycles and therefor become smaller and more manageable.

  • Blended 3 uses OSGi as it’s runtime within the JVM. Looking at ZIO and it’s ecosystem the first thing to note is that there is no OSGi support out of the box. So the question rises (again) whether Blended shall stick to OSGi or not. At the end of the day OSGi was chosen because when Blended was created, which was before today’s virtualization techniques where available. We did need a runtime allowing in-place-updates of the deployed jars via a management API.

    As of version 3, the management API is read-only, the requirement for in place updates has vanished in favor of bundling the Blended based applications statically and use Ansible to roll out software updates - replacing and restarting the entire JVM. As a result, OSGI is merely used to maintain the dependencies between various services within the JVM to make sure everything is wired up correctly.

    From my understanding, within the ZIO ecosystem there are different options which at least deserve a closer look. One of the options is the distage framework which seems to promise most of the requirements we might have in our packaging.

    As a consequence I will concentrate on the module functionality first without considering OSGi and will consider the packaging and dependency injection once I have ported a sufficient number of modules to test a small application.