Microservice Terminal Simulator

The project is getting larger by the day. There are already 3 services, a shared math library, and the Unity visualization and many more services planned. Starting up the demo requires 5 applications to startup. Because of this, Pieter and I decided in our weekly meeting to focus on containerization and deployment to ease development process early on. Before working on the Docker migration I decided to start with the framework to make sure gRPC initialization code is more centralized in a library which would make the migration to Docker easier.

Distributed Data Framework

When deciding to migrate towards Docker deployment, I wanted to make sure that the code has no direct references to the gRPC code. When thinking of use cases of this project and how to keep it as simple as possible, I came up with a framework design that handles the distributed data.

For example, let’s say you want to get the position of an object and move it and update the data. The previous code to achieve this would look like this:

Old way

There are a lot of direct references gRPC generated code. The code has a lot of fluff that could easily need to be changed if the service communication changes. This is a straightforward case where data from only one service is requested and updated. When using multiple data sources this would get messy quickly.

So I created the framework to handle most of these steps. This same functionality can be done with framework like so:

Using the framework

The framework executes the same code as the previous example. It does so by finding which service defines PosX and PosY in their protobuffer file, initializing the service client and translating between data models and gRPC models. This framework can handle data requests from several services and merge them into appropriate data models. It works quite well. Data from several services should work as well but has not been properly tested yet.

Future improvements

There are several improvements that could be made. There is a lot of room for performance improvement by caching reflection calls and generating delegates. However, the time it takes to execute the gRPC call dwarfs any inefficiencies of my implementation. I expect I added a maximum of 0.5 milliseconds to each call. The gRPC call itself takes anywhere from 4 to 20 milliseconds. So, it does not seem fruitful at this point to optimize the implementation when it is such a small part of the performance.

I want to add a smart caching mechanism in the future. When requesting data, it does not always need to be the most up to data. By building an optional caching mechanism where GetData only executes gRPC calls when the cached data is older than 200ms or so could provide a lot of performance benefits.

To update the data of a service one needs to provide the whole data model. So, to achieve the UpdateData implementation the framework does a GetData call before updating the data. So UpdateData does two gRPC calls instead of one. This is quite the performance hit as gRPC calls are quite slow. This should be optimized out. The caching system described in the last paragraph should make this relatively easy by using the cached data for the Update call. Issues may arise from simultaneous updates using cached data where the services aren’t idempotent. But this can be fixed if it ever becomes a problem.

Functionality Research Document

I finally started on writing down the functionality research I have done during the first weeks. In this document I describe which functionality and goals Terminal Operating Systems have. This should answer one of my research questions.

Docker

After the framework implementation I started by researching existing tools and decided that Docker is the most appropriate containerization tool. I looked at container orchestration tools that work well with docker. Kubernetes and docker-compose seemed most appropriate for this use case. I decided to use docker-compose for now because it’s ease of use and clear migration path to Kubernetes. The research and conclusion are more described in a research document in more detail.

Implementation Progres

Getting the docker images to work took some time. I created dockerfiles using the .NET provided templates. Unfortunately, it did not work at first. After some configuration I managed to get it working. There are still some issues with the gRPC connection. The docker-compose file is setup and that seems to be working. Because of the time spent on the framework I did not manage to finish the docker migration. There is an issue with the internal communication that must be fixed. I will pick this up next week.

I am quite pleased with the result of this week. I even worked during the night because I wanted to get the framework implementation working and found it quite fun. However, the documentation is behind schedule. I need to focus more on this to keep Fontys properly engaged with my assignment.