tty4.dev https://tty4.dev/ Recent content on tty4.dev Hugo en-us © Dennis Kawurek Sat, 14 Mar 2026 15:38:00 +0100 Usage of Git worktrees https://tty4.dev/development/2026-03-14-use-git-worktree/ Sat, 14 Mar 2026 15:38:00 +0100 https://tty4.dev/development/2026-03-14-use-git-worktree/ <p>Recently, I read more and more about <a href="https://git-scm.com/docs/git-worktree">Git working trees</a> being used for parallel agents for example in <a href="https://cursor.com/docs/configuration/worktrees">Cursor</a> or <a href="https://code.visualstudio.com/docs/copilot/agents/copilot-cli#_isolation-modes">VSCode</a>.</p> <p>However, worktrees are also useful for maintaining an uninterrupted workflow when working on multiple things within the same repository.</p> <p><code>git worktree</code> commands are used to manage working trees.<br> They are executed from the main repository.</p> <h2 id="create-a-worktree">Create a worktree</h2> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git worktree add -b feat-a ../feat-a main </span></span></code></pre></div><p>What this does:</p> <ul> <li>Creates a directory relative to the repository in <code>../feat-a</code></li> <li>Checks out a new branch named <code>feat-a</code> in that directory</li> <li>The branch starts from the commit currently pointed to by <code>main</code></li> </ul> <p>The directory structure will look something like this with the given branch and commit:</p> Client-side inference using onnxruntime https://tty4.dev/development/2026-02-26-onnxruntime-ml-on-edge/ Thu, 26 Feb 2026 20:20:00 +0100 https://tty4.dev/development/2026-02-26-onnxruntime-ml-on-edge/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p><em>tl;dr</em> you can use the model <a href="https://tty4.dev/tools/wasm-ml/">here</a>, play around and check the code.</p> <p>The <a href="https://onnxruntime.ai/docs/tutorials/web/">ONNX Runtime for web</a> makes it possible to serve an ML model and run inference within browsers. This enables ML on Edge and enhances the privacy of the user.</p> <p>Using the runtime I serve my latest favour model. It&rsquo;s possible to use it <a href="https://tty4.dev/tools/wasm-ml/">here</a>. Type in the data and see how likely I&rsquo;d like the article (calculation skews are possible).</p> 5 practical use-cases for an ML-powered RSS digest https://tty4.dev/development/2026-02-23-using-rss-digest/ Mon, 23 Feb 2026 18:54:00 +0100 https://tty4.dev/development/2026-02-23-using-rss-digest/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>Creating an RSS digest is fun, but it&rsquo;s even more fun, when you have a real use-case for it.</p> <p>So this post checks the different possible ways of using it. Keep in mind that these are all ideas I have to use it, I&rsquo;m sure there are many more, you can let me know if you have a nice idea. :)</p> Optimizing a model by using metrics https://tty4.dev/development/2026-02-20-optimizing-model-by-metrics/ Fri, 20 Feb 2026 21:17:00 +0100 https://tty4.dev/development/2026-02-20-optimizing-model-by-metrics/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>The <a href="https://tty4.dev/development/2026-02-13-defining-tracking-training-machine-learning-model/">past post</a> mentioned metrics to track the performance of a model.</p> <p>This post shows how to use them for optimizing a model and how it helped to improve the AUC from 0.59 to 0.84.</p> <h2 id="tracking-metrics">Tracking metrics</h2> <p>During the model training the following five metrics have been tracked:</p> <ul> <li><strong>Loss</strong>: Measures prediction error; if training loss drops while validation loss climbs, the model is likely overfitting. This means the model is memorizing rather than generalizing.</li> <li><strong>AUC</strong> (Area Under the ROC Curve): Evaluates how well the model ranks positives over negatives.</li> <li><strong>Precision</strong>: The accuracy of positive predictions, or the percentage of &ldquo;flagged&rdquo; articles that were actually correct.</li> <li><strong>Recall</strong>: The model&rsquo;s &ldquo;find rate,&rdquo; measuring what percentage of all truly positive articles were successfully identified.</li> <li><strong>F1 Score</strong>: The harmonic mean that balances precision and recall into a single representative number.</li> </ul> <p>These metrics can be used to track training progress and use them for model optimizations!</p> Defining, tracking and training a machine learning model https://tty4.dev/development/2026-02-13-defining-tracking-training-machine-learning-model/ Fri, 13 Feb 2026 21:39:00 +0100 https://tty4.dev/development/2026-02-13-defining-tracking-training-machine-learning-model/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>This continues the journey on creating a RSS digest. The final step to get a working machine learning model is to implement the training pipeline.</p> <p>In a <a href="https://tty4.dev/development/2026-02-07-dataset-training-pipeline-preparations/">previous post</a> the data has been prepared. This post shows how to define the model, train it and use it for predictions.</p> <h2 id="defining-the-model">Defining the model</h2> <p>PyTorchs <code>nn.Module</code> can be sub-classed and <code>nn.Sequential</code> used to define the sequence of layers to be used in a model:</p> Building an RSS digest: All posts https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/ Fri, 13 Feb 2026 21:21:00 +0100 https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/ <p>This aims to give a better structure to read the posts about the RSS digest implementation.</p> <p>To give a better entrypoint about the existing posts and in which order to read what, if interested:</p> <ul> <li><a href="https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest/">Building an ML-powered RSS digest</a> outlines the idea and motivation.</li> <li><a href="https://tty4.dev/development/2026-01-17-technical-view-rss-digest/">Technical view of a recommendation system</a> is a good entrypoint for a general overview of the system.</li> <li><a href="https://tty4.dev/development/2026-01-04-collect-labels-for-rss-digest/">Collecting labels to train a model for an RSS digest</a> collects the labels used for the model.</li> <li><a href="https://tty4.dev/development/2026-01-08-feature-engineering/">Selecting the features for the RSS digest</a> uses feature engineering to collect the input data.</li> <li><a href="https://tty4.dev/development/2026-02-03-training-two-models/">Training two models for better results in recommendation systems</a> describes the idea of training two models for getting better results in the RSS digest.</li> <li><a href="https://tty4.dev/development/2026-02-07-dataset-training-pipeline-preparations/">Dataset preparations for training a machine learning model</a> prepares the data for the training.</li> <li><a href="https://tty4.dev/development/2026-02-13-defining-tracking-training-machine-learning-model/">Defining, tracking and training a machine learning model</a> trains the model and tracks metrics.</li> <li><a href="https://tty4.dev/development/2026-02-15-optimizing-model-by-metrics/">Optimizing a model by using metrics</a> has a closer look at the metrics and how to use them for optimizations.</li> <li><a href="https://tty4.dev/development/2026-02-23-building-rss-digest/">Optimizing a model by using metrics</a> checks some use-cases for the results the model gives.</li> <li><a href="https://tty4.dev/development/2026-02-26-onnxruntime-ml-on-edge">Client-side inference using onnxruntime</a> shows how to serve and use a model for inference in the browser.</li> </ul> <p>This list will be kept up to date.</p> Note taking in 2026 https://tty4.dev/development/2026-02-09-note-taking-2026/ Mon, 09 Feb 2026 10:17:00 +0100 https://tty4.dev/development/2026-02-09-note-taking-2026/ <p>Since my <a href="https://tty4.dev/no-category/knowledge-management-trilium/">last post</a> about note-taking many things have changed.</p> <p>Not so long after starting using Trilium I changed back to a flow based on the <a href="https://github.com/foambubble/foams">Foam VSCode extension</a> + VSCode snippets.</p> <p>Although Trilium provides many helpful features like a good text search, desktop app, mobile site and many more, I found very early that it&rsquo;s the wrong tool for my everyday usage as a software engineer.</p> <p>The main purpose of a note-taking tool should be to serve only one purpose: Let me write down things fast to find it later again. I don&rsquo;t want to maintain the tool and I don&rsquo;t want to need to re-discover features after an UI update etc.</p> Dataset preparations for training a machine learning model https://tty4.dev/development/2026-02-07-dataset-training-pipeline-preparations/ Sat, 07 Feb 2026 16:27:00 +0100 https://tty4.dev/development/2026-02-07-dataset-training-pipeline-preparations/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>Before running the training of a model the following things need to be done:</p> <ul> <li>Features need to be selected: deciding which input variables/attributes will be used to make predictions</li> <li>Featuresets need to be labelled: annotating the data with the correct outputs/targets</li> <li>Dataset need to be prepared: organizing features into a structured format suitable for training (handling missing values, splitting into train/test sets, normalization, &hellip;)</li> </ul> <p>This posts will give a sample on how to prepare the dataset based on the <a href="https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest/">recommendation system project</a>.</p> Training two models for better results in recommendation systems https://tty4.dev/development/2026-02-03-training-two-models/ Tue, 03 Feb 2026 19:08:00 +0100 https://tty4.dev/development/2026-02-03-training-two-models/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>The first version of the machine learning model I&rsquo;ve created for the <a href="https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest/">recommendation system</a> based on my RSS feed should be trained on two labels: The click &amp; favorite label.</p> <p>The initial idea was to have two labels represented as an array: <code>[ P(click), P(favoured) ]</code>.</p> <p>A clicked and favoured article would look like <code>[1, 1]</code>. And the model would return a prediction like <code>[0.98, 0.71]</code>.</p> docfind - the static search for the VSCode site https://tty4.dev/development/2026-01-25-static-search/ Sun, 25 Jan 2026 19:39:00 +0100 https://tty4.dev/development/2026-01-25-static-search/ <p>In the past I&rsquo;ve been writing about some approaches I did for creating a <a href="https://tty4.dev/no-category/static-search-released/">static search</a> for this page.</p> <p>The search is removed due to the additional maintenance needed when creating the site, but my interest in this topic still exists to some degree.</p> <p>Recently, I stumbled upon <a href="https://code.visualstudio.com/blogs/2026/01/15/docfind">this blog entry</a> about the static search created for the VSCode website. It&rsquo;s called <code>docfind</code> and uses also WebAssembly and a pre-created index.</p> <p>Under the hood docfind (which is open sourced at <a href="https://github.com/microsoft/docfind">GitHub</a>) uses a more engineered approach for fast search results. Also, it&rsquo;s nice to see that others are having same problems they solve with a comparable tech-stack.</p> Technical view of a recommendation system https://tty4.dev/development/2026-01-17-technical-view-rss-digest/ Sat, 17 Jan 2026 14:00:00 +0100 https://tty4.dev/development/2026-01-17-technical-view-rss-digest/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>This post in the series about building an RSS digest takes a look at the system.</p> <p>The following gives an overview of the components to be build.</p> <p><img src="img/ArticleFetcher.drawio.svg" alt=""></p> <p>The rectangles are components and the ellipses / circles are outputs.</p> <p>In the following sections the components and their outputs will be described more closely</p> <h2 id="the-labeller">The labeller</h2> <p>The Labeller is responsible for labelling the articles according to how the user interacts with the UI. This is an API which retrieves the following payload:</p> Selecting the features for the RSS digest https://tty4.dev/development/2026-01-08-feature-engineering/ Thu, 08 Jan 2026 21:00:21 +0100 https://tty4.dev/development/2026-01-08-feature-engineering/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>The previous post described how to label articles in a feed reader and store the labels.</p> <p>The post also contained this small view on the idea:</p> <blockquote> <p>Label articles → Create model → Use model to predict click/fav rate.</p> </blockquote> <p>This post will focus on a sub-step of the &ldquo;Create model&rdquo; part: <strong>Feature Engineering</strong>.</p> <p>Features are the input data for the model to be trained on. The Labels created in the <a href="https://tty4.dev/development/2026-01-04-collect-labels-for-rss-digest">post before</a> are the outputs the model should create based on the features.</p> Collecting labels to train a model for an RSS digest https://tty4.dev/development/2026-01-04-collect-labels-for-rss-digest/ Sun, 04 Jan 2026 14:08:11 +0100 https://tty4.dev/development/2026-01-04-collect-labels-for-rss-digest/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>As written in a <a href="https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest">post before</a> I aim to create an RSS digest for the feeds I subscribed to.</p> <p>The very high-level idea is:</p> <blockquote> <p>Label articles → Create model → Use model to predict click/fav rate.</p> </blockquote> <p>The first step towards this goal is to label articles in the feed reader.</p> <p>This article describes which labels will be collected and how/where they&rsquo;re stored. I used <a href="https://freshrss.org">FreshRSS</a>, but I&rsquo;ll keep this article agnostic to every other reader and describe the general ideas.</p> Building an ML-powered RSS digest https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest/ Fri, 02 Jan 2026 12:59:45 +0100 https://tty4.dev/development/2026-01-02-building-ml-powered-rss-digest/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>RSS is one of my favorite ways to consume tech news and blogs.</p> <p>Although it seems to be pretty dead for the broad masses, RSS feeds enable nice features through feed readers:</p> <ul> <li>Subscribe to and collect multiple sources at one place - no browsing and manual search needed.</li> <li>No push notifications - I can read it whenever I want.</li> <li>Self-hosted feed readers - I own my data and don&rsquo;t need to pay.</li> </ul> <p>I don&rsquo;t collect any statistics about it, but by my feeling I&rsquo;m pretty sure that my feed reader is one of the top 5 sites which I visit daily.</p> Temporary script, turned into a long-term solution https://tty4.dev/development/2025-12-21-evolving-temporary-solution/ Sun, 21 Dec 2025 12:46:05 +0100 https://tty4.dev/development/2025-12-21-evolving-temporary-solution/ <p>It was in one of my first jobs where I got tasked to serve a customer a file with some interesting data points about users of a system created for him.</p> <p>All the customer wanted to create a JSON file and place it on an SFTP server on regular basis, so that he could pull it and do some magic with Power BI.</p> <p>I was instructed to not use too many resources on it, because it was supposed to be only a temporary solution which was planned to be replaced within the next weeks and the customer won&rsquo;t pay much for it.</p> I deleted my Windows installation https://tty4.dev/development/2025-12-14-deleting-windows/ Sun, 14 Dec 2025 13:58:11 +0100 https://tty4.dev/development/2025-12-14-deleting-windows/ <p>Until recently I had two installations on my computer: One SSD contained my Windows installation and the other one Fedora.</p> <p>I decided to uninstall Windows, as I kept it mainly due to few reasons which proved wrong:</p> <ul> <li>Old data laying there</li> <li>Keep my Windows skills up to date</li> <li>For the case I need to solve a problem where Fedora can&rsquo;t help</li> </ul> <p>All of this proved wrong. I didn&rsquo;t boot Windows for problem solving since I installed Fedora.</p> Agent Skills - a thin alternative to the Model Context Protocol? https://tty4.dev/development/2025-12-13-skills-or-mcp/ Sat, 13 Dec 2025 16:40:02 +0100 https://tty4.dev/development/2025-12-13-skills-or-mcp/ <p>Just a year passed since the <a href="https://www.anthropic.com/news/model-context-protocol">Model Context Protocol</a> (MCP) has been introduced by Anthropic and despite of the traction it got in 2025, it got already concurrency by Anthropic itself: <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Agent Skills</a>.</p> <p>Also, it seems that OpenAI is <a href="https://simonwillison.net/2025/Dec/12/openai-skills/">experimenting with the idea</a>.</p> <p>This makes it worth to have a short look at the differences between the two. I also post some links below if you want to see examples for Agent Skills.</p> Improving loading times of this site https://tty4.dev/development/2025-10-18-improving-loading-times/ Sat, 18 Oct 2025 17:02:11 +0100 https://tty4.dev/development/2025-10-18-improving-loading-times/ <p>Although I haven&rsquo;t posted something on here for a pretty long-time I didn&rsquo;t forget that this page exists.</p> <p>Recently, I wanted to do something small. So, I checked this site for something which was bugging me already for a long time: The loading time and size of artifacts loaded.</p> <p>Although it is a very simple static site, I saw loading times of ~7-10 seconds in my self-experiments. Also, the size of the loaded page was around 6MB.</p> Building RAG is hard https://tty4.dev/development/2025-07-02-building-rag-is-hard/ Wed, 02 Jul 2025 20:51:09 +0100 https://tty4.dev/development/2025-07-02-building-rag-is-hard/ <p>Building Retrieval-augmented generation (RAG) is hard. At least if you want to get helpful and reliable results.</p> <p>Take as an example the IIOT (Industrial Internet of Things) world: No one wants to be responsible for a document management system powered by an LLM and RAG that cites incorrect results, potentially leading to machines being maintained improperly.</p> <p>At best, it costs the company money. At worst, human lives could be in danger.</p> How GitHub Copilot Serves 400 Million Completion Requests a Day https://tty4.dev/development/2025-06-30-copilot-400-million-requests/ Mon, 30 Jun 2025 20:11:12 +0200 https://tty4.dev/development/2025-06-30-copilot-400-million-requests/ <p>At QCon San Francisco Dave Cheney gave an insightful talk about how GitHub Copilot works under the hood and is able to serve 400 Million completion requests a day.</p> <p>Basically, every request goes through a Proxy that makes use of HTTP/2 and allows to keep the connection open. The powerful HTTP handler in Go makes it possible to drop requests without the need of closing a connection.</p> <p>The large load is handled by many different locations and concatenating the streams passed to a pool of connections that are talking with the model.</p> Experiencing Cross-Team Collaboration https://tty4.dev/development/2025-06-03-experiencing-cross-team-collaboration/ Tue, 03 Jun 2025 20:25:02 +0200 https://tty4.dev/development/2025-06-03-experiencing-cross-team-collaboration/ <p>The company I&rsquo;m working for is organizing an event which brings people from different teams together and allows them to work on a topic for one week.</p> <p>After day two I can say that I enjoy this very much as it enables knowledge sharing and collaboration between teams.</p> <p>The topic we&rsquo;re working on is exciting and makes fun. It&rsquo;s different from my usual day-to-day work and a great learning opportunity.</p> Cool URIs don't change https://tty4.dev/development/2025-04-28-cool-uris-dont-change/ Mon, 28 Apr 2025 19:02:11 +0100 https://tty4.dev/development/2025-04-28-cool-uris-dont-change/ <p>During Easter, there was a sale on domains at my hosting provider, and I saw my moment had come and secured a domain I had been eyeing for several weeks.</p> <p>As you can see, the site has now moved from <code>blog.dkwr.de</code> to <code>tty4.dev</code>. Somehow it all looks more pleasing to my eye, and besides that, the domain is just plain cool and hopefully easier to remember.</p> <p>But in keeping with <a href="https://www.w3.org/Provider/Style/URI">&ldquo;Cool URIs don&rsquo;t change&rdquo;</a>, all old references redirect to the new domain via <code>HTTP 301</code>. So nobody - including myself - needs to check everywhere if the domain still works. I also know how annoying it is when you&rsquo;ve saved bookmarks and after a few weeks the site is no longer available.</p> A New Home for Home Assistant https://tty4.dev/development/2025-02-04-homeassistant-futro-s920/ Tue, 04 Feb 2025 19:55:20 +0100 https://tty4.dev/development/2025-02-04-homeassistant-futro-s920/ <p>I was thinking about moving my Home Assistant instance away from my <a href="https://tty4.dev/no-category/2023-11-27-about-homelab/">homelab</a> to an own instance, e.g. to a Raspberry Pi.</p> <p>The strength of my homelab is that it&rsquo;s more powerful than a Raspberry Pi. But I found that this has also a few downsides like a higher power consumption. While the noise of the fan is ok for me, it also leads to a higher power consumption.</p> <p>Furthermore, devices on the other side of my flat have connection problems: Light bulbs occasionally loose their connection and raw bluetooth devices just can&rsquo;t connect.</p> Overview of Messaging in Distributed Systems https://tty4.dev/development/messaging-distributed-systems/ Fri, 31 Jan 2025 20:50:20 +0100 https://tty4.dev/development/messaging-distributed-systems/ <p>Messaging in distributed systems is a problem field which has own patterns and aspects. This post takes a brief look at the most important concepts and intends to be used as a primer for further research.</p> <h2 id="synchronous-vs-asynchronous">Synchronous vs. asynchronous</h2> <p>First, let&rsquo;s check the difference between <em>synchronous</em> and <em>asynchronous</em> requests:</p> <ul> <li>Synchronous: A service client makes a request to a service and expects an answer immediately.</li> <li>Asynchronous: A service client makes a request and isn&rsquo;t bound to the other service until it answers. The other service replies later when it&rsquo;s ready.</li> </ul> <p>Asynchronous requests enable loosely coupled services!</p> Implementing Retrieval-augmented generation (RAG) with an own LLM https://tty4.dev/development/implement-retrieval-augmented-generation/ Sun, 12 Jan 2025 13:46:19 +0100 https://tty4.dev/development/implement-retrieval-augmented-generation/ <p>In my last post I wrote about <a href="https://tty4.dev/development/2025-01-07-retrieval-augmented-generation-theory/">Retrieval-augmented generation (<em>RAG</em>) and why it&rsquo;s needed</a>.</p> <p>This post shows a practical implementation for the LLM created in <a href="https://github.com/denniskawurek/llm-from-scratch">my repository</a>.</p> <h2 id="choosing-a-framework">Choosing a Framework</h2> <p>RAG can be implemented manually, but there are a few frameworks which help to implement the pipeline and make things easier.</p> <p>I decided to use <a href="https://www.llamaindex.ai/">LlamaIndex</a> for this post, but there are few others like: <a href="https://haystack.deepset.ai/">Haystack</a> or <a href="https://www.langchain.com/">LangChain</a>.</p> <p>There&rsquo;s a link for a tutorial at the bottom of the page if you&rsquo;re interested how to do RAG in LangChain.</p> Retrieval-Augmented Generation in Large Language Models: The Theory https://tty4.dev/development/2025-01-07-retrieval-augmented-generation-theory/ Tue, 07 Jan 2025 20:38:15 +0100 https://tty4.dev/development/2025-01-07-retrieval-augmented-generation-theory/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>In my former posts I wrote about my experiences in building an LLM from Scratch.</p> <p>While <a href="https://tty4.dev/development/2025-01-03-fine-tuning-llms">fine-tuning</a> worked well to make the model better in a specific domain, it opens up the question if the model needs to be re-trained every time when new information is available or how to enhance it with domain-specific knowledge.</p> <h2 id="the-need-for-retrieval-augmented-generation">The need for Retrieval-augmented generation</h2> <p>Let&rsquo;s use a coding assistant as an example:</p> Fine-tuning LLMs Locally vs. In The Cloud https://tty4.dev/development/2025-01-03-fine-tuning-llms/ Fri, 03 Jan 2025 11:12:19 +0100 https://tty4.dev/development/2025-01-03-fine-tuning-llms/ <div class="alert-low"> This post is part of a series. <a href="https://tty4.dev/development/2026-02-13-building-rss-digest-all-posts/">Here</a> is an overview of all posts. </div> <p>This is a short write-up about my experience of training and fine-tuning an LLM. It intends to give an overview about the dimensions which impact good hardware has on training.</p> <p>I&rsquo;ve done this in the course of working with the &ldquo;Build an LLM from Scratch&rdquo; book. You can find <a href="https://tty4.dev/development/building-llm-from-scratch">my review</a> in another post, if interested.</p> <p>This post will give a few numbers to get a feeling for the resources needed and the costs involved. I&rsquo;ll outline my personal opinion about the different ways I trained the model.</p> Book review: Building an LLM (From Scratch) https://tty4.dev/development/building-llm-from-scratch/ Thu, 02 Jan 2025 10:01:19 +0100 https://tty4.dev/development/building-llm-from-scratch/ <p>There are many free resources which try to explain what LLMs are and how they work internally. Same applies for implementations. But looking at code and explanations didn&rsquo;t give me the feeling that I really understand from the ground up how they work. Especially what exactly the transformer architecture is and how it&rsquo;s implemented.</p> <p>Luckily, 2024 Sebastian Raschka published the book <a href="https://www.manning.com/books/build-a-large-language-model-from-scratch"><em>Build a Large Language Model (From Scratch)</em></a> at Manning.</p> <p>I recommend this for anyone, who&rsquo;s interested in building an LLM by himself to understand the transformer architecture etc.</p> Visiting the largest computer museum of the world https://tty4.dev/no-category/2024-12-29-visiting-hnf-largest-computer-museum/ Sun, 29 Dec 2024 21:46:48 +0100 https://tty4.dev/no-category/2024-12-29-visiting-hnf-largest-computer-museum/ <p>When driving in Germany on the Autobahn and passing a medium-sized or larger city you&rsquo;ll see a sign which shows a tourist attraction nearby.</p> <p>For Paderborn it&rsquo;s the <a href="https://www.hnf.de">Heinz Nixdorf MuseumsForum</a> (short: HNF). The HNF is one of the (if not <em>the</em>) largest computer museum of the world.</p> <p>This year a dream came true and I visited it.</p> <p>The museum isn&rsquo;t just about computers: It gives visitors a journey through the history of information and information technology. It shows how information was preserved and carried from one point to another in human history.</p> Retrospective on Androids: The Team that Built the Android Operating System https://tty4.dev/development/retrospective-androids-book/ Mon, 23 Dec 2024 19:46:11 +0200 https://tty4.dev/development/retrospective-androids-book/ <p>I just completed <em>Androids: The Team that Built the Android Operating System</em> by Chet Haase and can fully recommend this book. It&rsquo;s a book which provides insights into the first days of the Android OS.</p> <p>The book gives an overview of why Android was started and which underlying ideas led to the big market growth in a highly competitive field.</p> <p>Also, it shows some tricks that were used to work in such a resource-constrained world as it was when the first smartphones appeared.</p> Hexagonal Architecture: The Good And The Hard Parts https://tty4.dev/development/hexagonal-architecture-the-good-and-hard-parts/ Fri, 20 Dec 2024 19:34:11 +0100 https://tty4.dev/development/hexagonal-architecture-the-good-and-hard-parts/ <p>There&rsquo;s a lot of stuff written about Hexagonal Architecture. I also wrote some things about it, but covered just the basics.</p> <p>Now with more experience of using the Hexagonal Architecture style in Java with Spring Boot, I thought it&rsquo;s time to reflect what are the good and the hard parts of it.</p> <h2 id="few-words-for-the-beginning">Few Words For The Beginning</h2> <p>You may notice that I don&rsquo;t write &ldquo;The Good And The Bad Parts&rdquo;. That&rsquo;s because on one side I really like the application of Hexagonal Architecture in the context of professional work. On the other side I found that the &ldquo;hard parts&rdquo; are a challenge in nearly every architecture style and not just in Hexagonal Architecture.</p> Move Code Changes Between Branches With Git Patch Files https://tty4.dev/development/git-patchfiles/ Thu, 05 Dec 2024 19:46:11 +0200 https://tty4.dev/development/git-patchfiles/ <p>With patch files Git provides an easy-to-use way to move code changes between branches.</p> <p>A patch file contains information about the changed lines in a comparable way like it&rsquo;s shown when doing a <code>git diff</code>.</p> <p>Here&rsquo;s how to use it.</p> <h2 id="move-code-from-branch-a-to-branch-b">Move code from branch A to branch B</h2> <p>Move code from branch <code>A</code> to branch <code>B</code>, where branch <code>B</code> does <em>not</em> depend on branch <code>A</code>.</p> <ol> <li>On branch <code>A</code> create patch file:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git format-patch -1 COMMIT_ID </span></span></code></pre></div><ol start="2"> <li>On branch <code>B</code> apply the created patch file:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git apply PATCH_FILE </span></span></code></pre></div><ol start="3"> <li>Interactively choose hunks to add:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>git add -p </span></span></code></pre></div><p>If branch B depends on branch A and you want to move a change to branch B, then you can do the same. But you need to remove the conflicts.</p> Use dnsmasq for local DNS with wildcard support https://tty4.dev/development/local-dnsmasq-wildcard/ Sun, 01 Dec 2024 15:38:34 +0100 https://tty4.dev/development/local-dnsmasq-wildcard/ <p>Recently, I set up new projects in my <a href="https://tty4.dev/no-category/2023-11-27-about-homelab">homelab</a>.</p> <p>Generally, my homelab is reachable via the domain <code>atlas.internal</code>.</p> <p>All projects have their own subdomains like <code>git.atlas.internal</code>, <code>files.atlas.internal</code>, etc..</p> <p>But beside of that I can reach them also via an opened port.</p> <p>Security-wise that&rsquo;s no problem, as my homelab is reachable only within my home network.</p> <h2 id="the-annoyances-of-this-setup">The annoyances of this setup</h2> <p>Anyway, I don&rsquo;t like this:</p> <ul> <li>I need to map ports around and remember them. (Sub-)Domains are far easier to remember.</li> <li>On my computer I need to extend the <code>/etc/hosts</code> file every time I add a new service.</li> </ul> <p>The last problem is really annoying, as <code>/etc/hosts</code> doesn&rsquo;t support wildcard domains. So, when I add or remove a service, I need to maintain the <code>hosts</code> file.</p> Trying local LLMs https://tty4.dev/development/local-llms/ Sat, 16 Nov 2024 11:40:34 +0200 https://tty4.dev/development/local-llms/ <p>There are quite a lot of tools which try to give the same experience as ChatGPT or claude.ai: A nice UI with model selections etc.</p> <p>Recently, I just wanted to try out different models and found once more that Simon Willisons <a href="https://github.com/simonw/llm">llm</a> was the best hassle-free solution for this.</p> <p>Just install the Python package and you&rsquo;re good to go (see the <a href="https://llm.datasette.io/en/stable/setup.html#">official page</a>).</p> <p><code>llm</code> integrates different plugins to support different formats. One of these is the <code>gpt4all</code> plugin which are available by the <a href="https://www.nomic.ai/gpt4all">GPT4All</a> project</p> Generating recommendations for blog posts with machine learning https://tty4.dev/development/generate-recommendations-published/ Sun, 27 Oct 2024 20:10:18 +0200 https://tty4.dev/development/generate-recommendations-published/ <p>I already wrote twice how to generate recommendations for blog posts with machine learning:</p> <ul> <li><a href="https://tty4.dev/development/calculate-similarity-of-posts/">Calculate automatically the similarity between my posts</a></li> <li><a href="https://tty4.dev/development/better-similarities">Getting a higher confidence in spaCy similarity</a></li> </ul> <p>I&rsquo;m pretty happy about the results and it works without any problems since one year. So, I&rsquo;ve done a little cleanup of the code and decided to publish it.</p> <p>You can find the code and general instructions in the <a href="https://github.com/denniskawurek/generate-recommendations">repository on GitHub</a>.</p> <h2 id="use-the-recommendations-for-hugo">Use the recommendations for Hugo</h2> <p>Here&rsquo;s a small extra for Hugo users.</p> Git rebase fails because of uncommitted changes, but there are no uncommitted changes https://tty4.dev/development/git-rebase-fail/ Sat, 26 Oct 2024 15:53:28 +0200 https://tty4.dev/development/git-rebase-fail/ <p>Recently I got the following error when I was doing a <code>git rebase master</code>:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>error: Your local changes to the following files would be overwritten by checkout: </span></span><span style="display:flex;"><span> &lt;Omitted list of files&gt; </span></span><span style="display:flex;"><span>Please commit your changes or stash them before you switch branches. </span></span><span style="display:flex;"><span>Aborting </span></span><span style="display:flex;"><span>error: could not detach HEAD </span></span></code></pre></div><p><code>git status</code> showed no unstaged changes, and I confirmed that there were no changes in <code>.gitignore</code>d files.&quot;</p> <p>Normally, it helped to execute the following on the <code>branch-to-rebase</code>:</p> Define An Extensible Or Generic JPA Repository https://tty4.dev/development/spring-jpa-generic-repository/ Sun, 20 Oct 2024 11:22:29 +0200 https://tty4.dev/development/spring-jpa-generic-repository/ <p>The <code>@NoRepositoryBean</code> annotation allows to define an extensible / generic JPA repository in Spring Boot:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@NoRepositoryBean</span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">BaseAnimalRepository</span><span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> <span style="color:#66d9ef">extends</span> JpaRepository<span style="color:#f92672">&lt;</span>T, Long<span style="color:#f92672">&gt;</span> </span></span></code></pre></div><p>From the <a href="https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/NoRepositoryBean.html">documentation</a> of the <code>@NoRepositoryBean</code>:</p> <blockquote> <p>This will typically be used when providing an extended base interface for all repositories in combination with a custom repository base class to implement methods declared in that intermediate interface. In this case you typically derive your concrete repository interfaces from the intermediate one but don&rsquo;t want to create a Spring bean for the intermediate interface.</p> Capture Logs In Spring Boot Tests https://tty4.dev/development/spring-capture-logs/ Fri, 11 Oct 2024 20:01:10 +0200 https://tty4.dev/development/spring-capture-logs/ <p>To assert that a specific message is logged in a Spring Boot application, the <a href="https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/system/OutputCaptureExtension.html"><code>OutputCaptureExtension</code></a> can be used.</p> <p>Here&rsquo;s an example test:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@ExtendWith</span>(OutputCaptureExtension.<span style="color:#a6e22e">class</span>) </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MyServiceTest</span> { </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> MyService myService <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> MyService(); </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">final</span> String MESSAGE <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Hello World!&#34;</span>; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Test</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">testLogMessage</span>(CapturedOutput output) { </span></span><span style="display:flex;"><span> myService.<span style="color:#a6e22e">logMessage</span>(MESSAGE); </span></span><span style="display:flex;"><span> assertThat(output.<span style="color:#a6e22e">getOut</span>()).<span style="color:#a6e22e">contains</span>(MESSAGE); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>The <a href="https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/system/CapturedOutput.html"><code>CapturedOutput</code></a> API serves different methods to get the output.</p> Ceramic Designs Generated By Claude https://tty4.dev/no-category/claude-ceramics/ Thu, 10 Oct 2024 19:39:10 +0200 https://tty4.dev/no-category/claude-ceramics/ <p>Few weeks ago my girlfriend took me to a pottery workshop.</p> <p>While I like the idea behind it (painting, firing, &hellip;) I faced one problem: The last time I was doing art by intention was probably 12 years ago in school.</p> <p>I got told that the best thing is to paint something &lsquo;simple&rsquo; and to paint it according to a template.</p> <p>A color gradient is maybe the most simple thing, but I thought it would be boring to paint a gradient for 2.5 hours.</p> Cleaning Up My Digital Life https://tty4.dev/no-category/cleaning-up/ Sat, 07 Sep 2024 09:39:10 +0200 https://tty4.dev/no-category/cleaning-up/ <p>Currently, I don&rsquo;t blog that much. This site has a second priority due to summer and other things I do (which I may also be blogging about in the future).</p> <p>One of these things is cleaning up my digital life.</p> <p>So, first I have resolved some issues on <a href="https://tty4.dev/no-category/2023-11-27-about-homelab">my homelab</a>, refactored the docker compose scripts and cleaned old data. It feels more organized and more stable now. Furthermore it reflects my current knowledge of docker compose, now. I decided to not rewrite everything, but refactor it. And I think it was a good idea as it didn&rsquo;t take that long.</p> Revisiting the HTC Desire (Bravo) https://tty4.dev/no-category/htc-desire-today/ Wed, 21 Aug 2024 17:51:10 +0200 https://tty4.dev/no-category/htc-desire-today/ <p>Recently I was thinking about the Smartphones I had and remembered my first one: The <a href="https://en.wikipedia.org/wiki/HTC_Desire">HTC Desire</a> (codename <em>Bravo</em>, sometimes also <em>A8181</em>).</p> <p>That was 13 years ago!</p> <p>Out of interest I checked eBay and saw that someone was selling it for 15€.</p> <p>I&rsquo;m not an impulsive buyer, but this time nostalgia won.</p> <p>When I unpacked it first, I was surprised. I didn&rsquo;t remember it being <em>that</em> small.</p> <p>Here&rsquo;s a comparison between an iPhone 13 (6.1-inch) and the HTC Desire (3.7-inch):</p> Wasm Component Model By Example https://tty4.dev/development/wasm-component-model-example/ Thu, 25 Apr 2024 20:49:47 +0200 https://tty4.dev/development/wasm-component-model-example/ <p>It&rsquo;s time to get some practice after answering what the <a href="https://tty4.dev/development/wasm-component-model">Wasm component model</a> is.</p> <p>You can find the code at <a href="https://github.com/denniskawurek/wasm-components-sample">GitHub</a></p> <h2 id="preparations">Preparations</h2> <p>Before we start, prepare the environment:</p> <ul> <li>You need the latest version of Rust.</li> <li>Install <a href="https://github.com/bytecodealliance/cargo-component">cargo component</a>:</li> </ul> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cargo install cargo-component </span></span></code></pre></div><ul> <li>Install <a href="https://github.com/bytecodealliance/wasm-tools">wasm-tools</a></li> </ul> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>cargo install wasm-tools </span></span></code></pre></div><ul> <li>Install a Wasm runtime which supports the component model, like <a href="https://github.com/bytecodealliance/wasmtime">wasmtime</a>:</li> </ul> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>curl https://wasmtime.dev/install.sh -sSf | bash </span></span></code></pre></div><h2 id="overview-of-the-application">Overview of the application</h2> <p>The application is simple: A component <code>string-operations</code> which exports operations on strings. In this example it&rsquo;s a function that takes one string parameter and returns its length.</p> Wasm: What Is The Component Model https://tty4.dev/development/wasm-component-model/ Tue, 23 Apr 2024 20:30:10 +0200 https://tty4.dev/development/wasm-component-model/ <p>In the beginning of this year the WASI preview 2 reached a milestone <a href="https://github.com/WebAssembly/WASI/pull/577">by being launched</a>.</p> <p>It got enabled by two things: the WIT IDL and the <a href="https://github.com/WebAssembly/component-model">component model</a>. Let&rsquo;s check in this post what it is.</p> <p>From the <a href="https://github.com/WebAssembly/WASI/blob/main/preview2/README.md">WASI repository</a>:</p> <blockquote> <p>WASI Preview 2 represents a major milestone for WASI. It marks the moment when WASI has fully rebased on the Wit IDL and the component model type system and semantics, making it modular, fully virtualizable, and accessible to a wide variety of source languages.</p> Recommended Apps, Websites And Services For Traveling To Japan https://tty4.dev/no-category/japan-technical-recommendations/ Mon, 15 Apr 2024 20:16:10 +0200 https://tty4.dev/no-category/japan-technical-recommendations/ <p><img src="https://tty4.dev/japan/tips/cherryblossom.jpg" alt=""></p> <p>I&rsquo;m back from Japan and want to give a small collection of tips for apps, websites and services which I found useful before and during my trip.</p> <h2 id="esim">eSIM</h2> <p>First, I really recommend to get an eSIM.</p> <p>This will help you to get around easily. Navigating and checking out for restaurants or even translation or product searches will make your life a lot easier.</p> <p>I think that having an internet connection took out a lot of potential stress during this trip: We took only once a wrong train. And even then it was just a few seconds to get an alternative route.</p> Wasm: The Garbage Collection proposal https://tty4.dev/development/wasm-gc-why/ Sun, 14 Apr 2024 10:24:10 +0200 https://tty4.dev/development/wasm-gc-why/ <p>While you can compile languages that rely on a Garbage Collector to Wasm already, there is a big downside: They need to ship with a Garbage Collector.</p> <p>For example: PHP to Wasm compiled modules ship with a compiled GC. That&rsquo;s contrary to the idea of Webassembly to serve thin modules.</p> <p>Furthermore it doesn&rsquo;t make much sense to come with a compiled GC, because the host most of the time already has a Garbage Collector.</p> Deep Work For Developers https://tty4.dev/development/deep-work/ Mon, 25 Mar 2024 19:26:10 +0100 https://tty4.dev/development/deep-work/ <p>I have reservations about fully embracing Cal Newport&rsquo;s Deep Work 100% for software developers. It may work when you have a really high position where you can offload tasks to other people or where it is okay to just not answer emails for a whole day.</p> <h2 id="what-software-development-is-made-of">What Software Development is Made Of</h2> <p>Software development is a team sport. While I think that the best way of solving hard problems or one(!) task is actually when you get into a flow for 4-5 hours, it may not always be applicable. Sometimes you need to ask someone else for help and distract team members. Other times, someone else on your team needs your help and distracts you. And that&rsquo;s absolutely fine because that is what software development is made of.</p> Few Words About Using GitHub Copilot at work https://tty4.dev/development/copilot-thoughts/ Sun, 24 Mar 2024 10:26:10 +0100 https://tty4.dev/development/copilot-thoughts/ <p><em>tl;dr</em>:</p> <ul> <li>CoPilot can be really useful, and I don&rsquo;t want to miss it anymore.</li> <li>Nevertheless, it&rsquo;s important to keep in mind that it&rsquo;s currently not the universal remedy for developer productivity.</li> </ul> <p>By the end of the past year, the company I&rsquo;m working for bought Github Copilot licenses for (nearly?) all developers.</p> <p>I was curious if and in which way it helps me in my daily work. So, I took notes about my thoughts.</p> About: How Netflix Really Uses Java https://tty4.dev/development/about-how-netflix-really-uses-java/ Fri, 01 Mar 2024 20:26:10 +0100 https://tty4.dev/development/about-how-netflix-really-uses-java/ <p><a href="https://www.infoq.com/presentations/netflix-java/">This talk about &ldquo;How Netflix Really Uses Java&rdquo;</a> by Paul Bakker at QCon gives some interesting insights.</p> <p>Especially the first ~20 minutes about the overall architecture and how it evolved is nice to see.</p> <p>But, beside of that there were some other think pieces about using Java at higher scale:</p> <p>Netflix tries to save resources and money, by leveraging configurable Java features like Garbage Collection.</p> <p>Also, Netflix seemed to be trying to use <code>RxJava</code>, but found some downsides, as many devs did: It is really hard to understand and debug. Some people say it&rsquo;s hard to develop, because you need to exactly think about what <em>could</em> happen in beforehand. But this can also slow down development.</p> How Spring MVC Handles Requests: A Detailed View https://tty4.dev/development/spring/spring-mvc-request-handling-detail/ Sun, 04 Feb 2024 20:54:10 +0100 https://tty4.dev/development/spring/spring-mvc-request-handling-detail/ <p>In my last post I already about the high-level view of <a href="https://tty4.dev/development/spring/spring-mvc-high-level-view">how Spring MVC handles incoming requests</a>.</p> <h2 id="foreword">Foreword</h2> <p>This post provides a more detailed view of how Spring handles requests like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@PostMapping</span>(value <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;login&#34;</span>, consumes <span style="color:#f92672">=</span> MediaType.<span style="color:#a6e22e">APPLICATION_JSON_VALUE</span>) </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">login</span>(<span style="color:#a6e22e">@RequestBody</span> User user) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Logged in!&#34;</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>However, please note: It pertains to version 6.1 of the Spring Framework and may change in the future. Furthermore, it only covers the request processing from the filter chain until the resolution of the request body.</p> The high-level view of how Spring MVC handles requests https://tty4.dev/development/spring/spring-mvc-high-level-view/ Sat, 03 Feb 2024 19:01:10 +0100 https://tty4.dev/development/spring/spring-mvc-high-level-view/ <p>In the recent days I tried to understand how Spring Boot handles requests like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@PostMapping</span>(value <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;login&#34;</span>, consumes <span style="color:#f92672">=</span> MediaType.<span style="color:#a6e22e">APPLICATION_JSON_VALUE</span>) </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">login</span>(<span style="color:#a6e22e">@RequestBody</span> User user) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Logged in!&#34;</span>; </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>Spring MVC is responsible for the handling.</p> <p>The result is this high-level overview of it which separates its work in three blocks:</p> <p><img src="https://tty4.dev/spring/high_level_view_request_mapping_spring_boot.svg" alt=""></p> <p>A post with a more detailed view follows, but the main block with the component which controls everything is shown in the image: The <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html">DispatcherServlet</a>.</p> Spring: Bind values in x-www-form-urlencoded requests https://tty4.dev/development/spring/spring-boot-bind-param/ Tue, 30 Jan 2024 19:59:10 +0100 https://tty4.dev/development/spring/spring-boot-bind-param/ <p>In Spring Boot it&rsquo;s not possible to map request field names to property fields with <code>@JsonProperty</code> when a request method is consuming <code>application/x-www-form-urlencoded</code> type of requests. The reason is that there&rsquo;s no JSON payload in the body to consume.</p> <p>To resolve this <a href="https://docs.spring.io/spring-framework/docs/6.1.x/javadoc-api/org/springframework/web/bind/annotation/BindParam.html"><code>@BindParam</code></a> has to be used.</p> <p><strong>Note</strong> This feature is available since Spring 6.1. and Spring Boot 3.2.0.</p> <p>Check the following working example:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@RestController</span> </span></span><span style="display:flex;"><span><span style="color:#a6e22e">@RequestMapping</span>(path <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/user/&#34;</span>) </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">UserController</span> { </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@PostMapping</span>(value <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;login&#34;</span>, consumes <span style="color:#f92672">=</span> MediaType.<span style="color:#a6e22e">APPLICATION_FORM_URLENCODED_VALUE</span>) </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> String <span style="color:#a6e22e">login</span>(User user) { </span></span><span style="display:flex;"><span> <span style="color:#75715e">// user.username is not null</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Logged in!&#34;</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Data</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@AllArgsConstructor</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">User</span> { </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@BindParam</span>(<span style="color:#e6db74">&#34;user_name&#34;</span>) </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> String username; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> String password; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>The <code>username</code> property will get the value of the <code>user_name</code> field passed in the request. That behaves the same as using the <code>@JsonProperty</code> in requests of the type <code>application/json</code> with Jackson.</p> Aggregate exceptions in Spring with ControllerAdvice https://tty4.dev/development/spring-controlleradvice/ Sun, 21 Jan 2024 15:26:10 +0100 https://tty4.dev/development/spring-controlleradvice/ <p>Exceptions can affect the readability of code in a negative way. One way to mitigate this is to handle exceptions in one central place.</p> <p>In Spring Boot you can use <code>@ControllerAdvice</code> for this.</p> <p>I&rsquo;ll show an example, but keep in mind that there&rsquo;s more than shown here. So, read up the Javadoc for <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html">ControllerAdvice</a> to get more information on the features and ways to configure it.</p> <h2 id="the-problem">The problem</h2> <p>Let&rsquo;s say the following exception is thrown anywhere in the code:</p> Javadoc Generation Error: Bad HTML Entity https://tty4.dev/development/javadoc-use-ampersand/ Sun, 07 Jan 2024 12:24:10 +0100 https://tty4.dev/development/javadoc-use-ampersand/ <p>Recently when I tried to generate some Javadoc I got an error like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>error: bad HTML entity </span></span><span style="display:flex;"><span> * Get the current date &amp; time. </span></span></code></pre></div><p>The generation fails as Javadoc tries to get the character entity although an ampersand character (<code>&amp;</code>) is no character entity.</p> <p>I think of 3 different solutions for it.</p> <h2 id="use-the-character-entity">Use the character entity</h2> <p>One solution for it can be to just use the character entity:</p> Daily Bash Scripts https://tty4.dev/development/daily-bash-scripts/ Sat, 06 Jan 2024 18:26:32 +0100 https://tty4.dev/development/daily-bash-scripts/ <p>During my work I encountered repetitive commands which I reused by typing the command again or by using <code>CTRL + R</code> in the CLI.</p> <p>That approach is definitely not using the full power of a UNIX system and feels really counterintuitive.</p> <p>Furthermore, there are some things which I like to do in the morning and be part of my morning routine. By that I mean doing the following:</p> <ul> <li>Pull the latest changes from the remote repositories to my local repository and show me the changes. With that I see what happened the past day.</li> <li>Update all local images. This keeps the environment updated and by using always the latest images it&rsquo;s easier to notice side-effects of changes or if a change which came in the day before may affect todays work.</li> </ul> <p>I found this two things to be really helpful for me, but I didn&rsquo;t like to change to the directories and execute the commands in every directory.</p> Creating A Cloud Development Environment with code-server and nix shell https://tty4.dev/development/cde-code-server-nix-shell/ Thu, 04 Jan 2024 13:55:10 +0100 https://tty4.dev/development/cde-code-server-nix-shell/ <p><em>tl;dr</em>: Install <code>nix-shell</code> in the <a href="https://hub.docker.com/r/linuxserver/code-server">code-server</a> to have a nice development environment within the container. See <code>Dockerfile</code> below.</p> <p>Sometimes when I&rsquo;m traveling, I&rsquo;d like to use some time and write a blog post or develop small things on my homelab.</p> <p><img src="https://tty4.dev/code-server/code-server.png" alt=""></p> <h2 id="the-way-i-did-it-til-now">The way I did it til now</h2> <p>Usually, when I don&rsquo;t have my notebook with me I use my Chromebook to connect via Wireguard + SSH to my homelab and use a CLI editor to edit files etc.</p> Retrospective Of 2023 https://tty4.dev/no-category/retrospective-2023/ Sun, 31 Dec 2023 15:14:10 +0100 https://tty4.dev/no-category/retrospective-2023/ <p>2023 comes to an end, and it&rsquo;s time for some small retrospective.</p> <p>Generally, I&rsquo;d say it was a good year with a lot of challenges, new experiences, lots of traveling (counting personal and work-related travel, I visited 6 countries!) and new things I learned.</p> <p>It was the year where I probably read even more books from cover to cover than during my studies.</p> <p>Here are some of my thoughts on my personal development. I keep most of it job-related.</p> Suppressing unchecked cast warnings with Spring CastUtils https://tty4.dev/development/spring/spring-castutils/ Sun, 17 Dec 2023 23:24:10 +0100 https://tty4.dev/development/spring/spring-castutils/ <p>Let&rsquo;s say there are classes which are types of <code>Vehicle</code>. For example:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Bike</span> <span style="color:#66d9ef">extends</span> Vehicle {} </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Car</span> <span style="color:#66d9ef">extends</span> Vehicle {} </span></span></code></pre></div><p>Now, when there&rsquo;s a class with a method that returns a <code>T</code> it may look like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> T <span style="color:#a6e22e">getVehicle</span>(String type) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (Objects.<span style="color:#a6e22e">equals</span>(type, <span style="color:#e6db74">&#34;car&#34;</span>)) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> carWorker.<span style="color:#a6e22e">get</span>(); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> bikeWorker.<span style="color:#a6e22e">get</span>(); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p><small><em>Note</em>: That&rsquo;s a simplified method to focus on the problem.</small></p> <p>The IDE will show directly the error that <code>Vehicle</code> or <code>Car</code> is not of type <code>T</code>.</p> Clone before use: preventing TOCTOU attacks https://tty4.dev/development/prevent-toctou-attacks/ Sun, 17 Dec 2023 17:24:10 +0100 https://tty4.dev/development/prevent-toctou-attacks/ <p>Mutable variables can lead to vulnerabilities or unexpected behavior.</p> <p>Consider the following piece of code as a demonstration:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Java" data-lang="Java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">checkDomain</span>(HttpCookie httpCookie) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (httpCookie <span style="color:#f92672">==</span> <span style="color:#66d9ef">null</span>) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> NullPointerException(); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (httpCookie.<span style="color:#a6e22e">hasExpired</span>()) { </span></span><span style="display:flex;"><span> <span style="color:#75715e">// throw exception</span> </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> isDomainValid(httpCookie.<span style="color:#a6e22e">getDomain</span>()); </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>What could go wrong here? The problem with this code is that the method doesn&rsquo;t has any control about what happens with the <code>httpCookie</code>.</p> <p>So, the value of it could change between the check (<code>if</code>-clause) and the use (<code>return</code> statement). E.g. the cookie&rsquo;s domain could be changed before it is checked.</p> Using VSCode as a Java IDE https://tty4.dev/development/vscode-as-java-ide/ Sat, 16 Dec 2023 10:30:00 +0100 https://tty4.dev/development/vscode-as-java-ide/ <p>Some unsorted thoughts about using VSCode as a Java development environment.</p> <p>I tried more than once to use VSCode as my Java editor, but it didn&rsquo;t give me the same experience as IntelliJ IDEA.</p> <p>The UX was often really low and sometimes I just didn&rsquo;t understand why I got error pop-ups or where I can find the settings for my use case.</p> <p>There is a lot more to say like the low debugging-experience in VSCode while IntelliJ is outstanding in many matters or how tight the integration of Java into IntelliJ is.</p> Bring Java CRaC into your IDE (VSCode and a little bit about IntelliJ IDEA) https://tty4.dev/development/crac-ide/ Fri, 15 Dec 2023 15:46:00 +0100 https://tty4.dev/development/crac-ide/ <p>After <a href="https://tty4.dev/development/java-crac">looking at CRaC</a> I thought it would be nice to create checkpoints from within an IDE. It&rsquo;s more comfortable, to do it from within the IDE then using the CLI. Furthermore it may be easier to do it when you start your service every time with the <code>-XX:CRaCCheckpointTo</code> command.</p> <p>The code is in <a href="https://github.com/CRaC/example-spring-boot/compare/master...denniskawurek:crac-example-spring-boot:master">this commit on GitHub</a>.</p> <h2 id="key-takeaways">Key takeaways</h2> <p>Before I show you how I did it for VSCode here are some takeaways:</p> Java CRaC https://tty4.dev/development/java-crac/ Thu, 14 Dec 2023 16:46:00 +0100 https://tty4.dev/development/java-crac/ <p>Java is not a language which is famous for its fast startup-time when using a framework like Spring. Sometimes you need this when running time-sensitive applications or for example functions as a service which build on top of fast start-up times.</p> <p>Luckily there&rsquo;s some work regarding this like GraalVM or CDS.</p> <p>Another feature which promises to solve this problem is built on top of Linux&rsquo; <a href="https://criu.org/Main_Page">CRIU</a> and is called <em>Coordinated Restore at Checkpoint</em> or abbreviated <strong>CRaC</strong>.</p> about: HomeLab https://tty4.dev/no-category/2023-11-27-about-homelab/ Mon, 27 Nov 2023 19:46:00 +0100 https://tty4.dev/no-category/2023-11-27-about-homelab/ <p>In the end of the last year I started to build an own HomeLab. This post covers some superficial thoughts on this.</p> <h2 id="quick-facts">Quick facts</h2> <p>Here are some quick facts:</p> <ul> <li>I bought an used <strong>Fujitsu Esprimo Q920</strong>. Specs: <ul> <li>Costs: 148€</li> <li>Intel i5 (4.Gen) processor</li> <li>16GB RAM</li> <li>500GB SSD</li> <li>⌀11W Power consumption</li> </ul> </li> <li>I use Fedora as the OS.</li> <li>Everything runs inside my local network.</li> <li>I use Wireguard to reach it from the outside.</li> <li>I use docker compose to run services.</li> <li>Whenever possible I try to centralize services (e.g. using only one Postgres database).</li> </ul> <h2 id="tools-that-i-use">Tools that I use</h2> <p>The <a href="https://github.com/awesome-selfhosted/awesome-selfhosted">awesome-selfhosted</a> repository on GitHub gives a good list to grasp when searching for things to set up. With Docker it is really easy to try out software, run it and throw it away or keep it if needed.</p> Takeaways from the last company event https://tty4.dev/no-category/2023-11-26-company-event-days/ Sun, 26 Nov 2023 20:43:00 +0100 https://tty4.dev/no-category/2023-11-26-company-event-days/ <p>In the last week I attended a 2-day company event which included a lot of talks about corporate identity, branding, flair and more. All talkers were from management-level positions and so were the talks more on a high-level.</p> <p>However, I got some takeaways from the talks which help me to get a better feeling about corporate life and on how to work on things to align within the company. Some things are just &ldquo;lessons learned&rdquo; and don&rsquo;t need to be necessary true, but can help to initiate further thoughts on this.</p> Java Generics: Upper Bounded and Lower Bounded Wildcards https://tty4.dev/development/upper-lower-bounded-wildcards/ Thu, 16 Nov 2023 22:09:10 +0100 https://tty4.dev/development/upper-lower-bounded-wildcards/ <p>I already took a look at the <a href="https://tty4.dev/development/wildcards-what">difference between Wildcards and Types</a> in Java.</p> <p>Now it&rsquo;s time to take a closer look at Wildcards. Specifically, bounded and unbounded wildcards.</p> <p>You may sometimes came across this when seeing either this signature parameter or error message:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span>List<span style="color:#f92672">&lt;?</span> <span style="color:#66d9ef">super</span> Animal<span style="color:#f92672">&gt;</span> animals </span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>capture of <span style="color:#960050;background-color:#1e0010">?</span> <span style="color:#66d9ef">extends</span> Animal </span></span></code></pre></div><p>Let&rsquo;s see what this means.</p> <h2 id="bounded-wildcards">Bounded Wildcards</h2> <p>Generally, bounded wildcards can be used to relax or restrict wildcard variables.</p> <p>There are two of them: Lower Bounded Wildcards and Upper Bounded Wildcards.</p> Java Generics: When to use Wildcards and when to use Types? https://tty4.dev/development/wildcards-what/ Thu, 16 Nov 2023 22:09:00 +0100 https://tty4.dev/development/wildcards-what/ <p>When reading <em>Effective Java</em> by Joshua Bloch I came across the chapter about Generics and the difference between using Wildcards and Types.</p> <p>I did some further research to understand it more and this is the write up of it. Let it confuse you as much as me or let it be helpful.</p> <h2 id="when-to-use-which">When to use which</h2> <p>I found three statements which describe when to use what:</p> <ul> <li> <p><em>If a type parameter appears only once in the declaration, then replace it with a wildcard.</em> (<em>Effective Java</em> by Joshua Bloch)</p> Using LLMs for test data generation https://tty4.dev/development/llm-for-test-data-generation/ Mon, 23 Oct 2023 20:30:00 +0200 https://tty4.dev/development/llm-for-test-data-generation/ <p>Recently I had the idea to use generative AI for test data generation.</p> <p>To be precise: To generate JSON payloads out of an OpenAPI specification.</p> <p>The rough idea is:</p> <ol> <li>Read the OpenAPI spec.</li> <li>Pass the spec to <code>gpt-3.5-turbo</code> or a local running <code>Llama 2</code>. Give it instructions which type of request is expected (valid/non-valid request, XSS attack, &hellip;)</li> <li>Execute the requests</li> </ol> <p>I&rsquo;ve used the <a href="https://github.com/spring-petclinic/spring-petclinic-rest"><code>spring-petclinic-rest</code></a> project to test the idea and implementation.</p> The crucial distinction between equals and compareTo in Java https://tty4.dev/development/java-equals-comparable/ Thu, 21 Sep 2023 20:35:00 +0200 https://tty4.dev/development/java-equals-comparable/ <p>&hellip; or: Why 1 is not equals 1.0 when using BigDecimal.</p> <p>Languages have sometimes their own special behavior, which you need to know when you want to use it right.</p> <p>Sometimes you forget about it and then you remember some specific behavior when you try to use it.Let&rsquo;s take a look at the crucial difference between <code>equals</code> and <code>compareTo</code> in Java.</p> <h2 id="equals-of-bigdecimal"><code>equals</code> of <code>BigDecimal</code></h2> <p>Look at this two <code>BigDecimal</code>s:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">final</span> BigDecimal BIG_DECIMAL_1 <span style="color:#f92672">=</span> BigDecimal.<span style="color:#a6e22e">valueOf</span>(1); </span></span><span style="display:flex;"><span><span style="color:#66d9ef">final</span> BigDecimal BIG_DECIMAL_1_0 <span style="color:#f92672">=</span> BigDecimal.<span style="color:#a6e22e">valueOf</span>(1.<span style="color:#a6e22e">0</span>); </span></span></code></pre></div><p>Normally you&rsquo;d say that they have two equal values, and should be equal, because <code>1 = 1.0</code>.</p> A simple STOMP server & producer application https://tty4.dev/development/stomp-server-producer/ Sun, 10 Sep 2023 15:04:00 +0200 https://tty4.dev/development/stomp-server-producer/ <p>When developing a STOMP client I think it&rsquo;s nice to have a simple, local running STOMP server to subscribe to. That&rsquo;s what I recently did while updating my <a href="https://tty4.dev/development/spring/spring-stomp-client">STOMP in Spring Boot</a> article.</p> <p>Well, here&rsquo;s what worked for me:</p> <h2 id="server">Server</h2> <p>I used RabbitMQ as the server. For this I created this <code>Dockerfile</code> which activated STOMP within the RabbitMQ server.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Dockerfile" data-lang="Dockerfile"><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span><span style="color:#e6db74"> rabbitmq:latest</span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> rabbitmq-plugins enable --offline rabbitmq_web_stomp<span style="color:#960050;background-color:#1e0010"> </span></span></span></code></pre></div><p>Build and run it:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker build -t rabbitmq-custom . </span></span><span style="display:flex;"><span>docker run -i -p 61613:15674 </span></span></code></pre></div><h2 id="client-producer">Client (producer)</h2> <p>To produce messages which can be then consumed I&rsquo;ve used node and implemented the <code>@stomp/stompjs</code> library.</p> How to get Spring STOMP to parse messages successfully https://tty4.dev/development/spring/2023-09-10-spring-stomp-parsing-troubleshooting/ Sun, 10 Sep 2023 15:04:00 +0200 https://tty4.dev/development/spring/2023-09-10-spring-stomp-parsing-troubleshooting/ <p>Recently I updated my article about <a href="https://tty4.dev/development/spring/spring-stomp-client">STOMP in Spring Boot</a> and faced some issues to get a running example with the latest Spring Boot and websocket version.</p> <p>I tested the code with Spring Boot 3 and the version <code>3.2.0-SNAPSHOT</code> of the websocket library. My problem was that the message which I received wasn&rsquo;t parsed correct.</p> <p>Here are some notes to attack and prevent some of the appeared problems. Maybe they&rsquo;re helpful for someone (or me in the future).</p> The Dual Clocks of Computing: Time-of-Day and Monotonic https://tty4.dev/development/uncertain-time/ Tue, 29 Aug 2023 02:00:00 -0100 https://tty4.dev/development/uncertain-time/ <p>Our computers have two clocks:</p> <ul> <li>The time of day clock (also: <em>wall-clock time</em>).</li> <li>The monotonic clock.</li> </ul> <p>The following lines are dedicated to them.</p> <p>*Imagine <em>The Persistence of Memory</em> by Salvador Dali inserted here.*</p> <h2 id="time-of-day-clocks">Time-of-day clocks</h2> <p>The time-of-day clock returns the current time in accordance to a calendar.</p> <p>This is what you get when calling <code>System.currentTimeMillis()</code> in Java. It returns the passed time since <code>January 1, 1970, midnight (UTC)</code> using the Gregorian calendar and doesn&rsquo;t count leap seconds.</p> All Java 21 https://tty4.dev/development/all-java-21/ Mon, 21 Aug 2023 02:00:00 -0100 https://tty4.dev/development/all-java-21/ <p>Just few days left until Java 21 is generally available (September 19, 2023).</p> <p>I&rsquo;ve read and collected resources which discuss all the features which 21 will bring.</p> <p>You can follow the schedule one the page of the <a href="https://openjdk.org/projects/jdk/21/">OpenJDK</a> project.</p> <h2 id="the-four-available-jeps">The four available JEPs</h2> <p>Namely, there are 4 JEPs which are final and can be used in production:</p> <h3 id="jep-431-sequenced-collectionshttpsopenjdkorgjeps431">JEP 431: <a href="https://openjdk.org/jeps/431">Sequenced collections</a></h3> <p>Enhances the Java collection framework with a <code>Collection</code> that contains elements in a particular order. The <code>SequencedCollection</code> interface has been introduced for this.</p> Testcontainers in Spring Boot 3.1 https://tty4.dev/development/2023-08-18-testcontainers-spring-boot-3/ Fri, 18 Aug 2023 09:00:00 -0100 https://tty4.dev/development/2023-08-18-testcontainers-spring-boot-3/ <p>I already wrote two times about Testcontainers. Once I showed an example for the usage in <a href="https://tty4.dev/development/testcontainers-simple-example/">Spring Boot</a>. And the other time how to <a href="https://tty4.dev/development/2022-11-25-testcontainers-revisited/">manage the lifecycle state</a> and tear the connection down.</p> <p>Spring Boot 3.1 changed the way how you <em>can</em> use Testcontainers. There are a lot ways to use Testcontainers and now there&rsquo;s another, far easier way to do it.</p> <h2 id="before-spring-boot-31">Before Spring Boot 3.1</h2> <p>Before Spring Boot 3.1 you had two ways to connect to a Testcontainer.</p> JUnit 5: Annotations for @ParametrizedTest https://tty4.dev/development/parametrized-test/ Wed, 16 Aug 2023 02:00:00 -0100 https://tty4.dev/development/parametrized-test/ <p>I like the idea of <a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests">parametrized tests in JUnit 5</a>. Instead of writing 5 methods for one method and just changing the arguments, write the test case once and serve the arguments as a stream.</p> <p>This makes refactoring and maintenance of test code far easier.</p> <p>But, when you want to implement a ParametrizedTest you need to use the correct annotations and sources for the arguments.</p> <p>Check the following example:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#a6e22e">@ExtendWith</span>(SpringExtension.<span style="color:#a6e22e">class</span>) </span></span><span style="display:flex;"><span><span style="color:#a6e22e">@ContextConfiguration</span>(classes <span style="color:#f92672">=</span> {DeviceService.<span style="color:#a6e22e">class</span>}) </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">DeviceServiceTest</span> </span></span><span style="display:flex;"><span>{ </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@Autowired</span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> DeviceService deviceService; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> Stream<span style="color:#f92672">&lt;</span>Arguments<span style="color:#f92672">&gt;</span> <span style="color:#a6e22e">deviceArgs</span>() { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> Stream.<span style="color:#a6e22e">of</span>( </span></span><span style="display:flex;"><span> Arguments.<span style="color:#a6e22e">of</span>(Device.<span style="color:#a6e22e">builder</span>().<span style="color:#a6e22e">deviceId</span>(1).<span style="color:#a6e22e">name</span>(<span style="color:#e6db74">&#34;Raspberry Pi&#34;</span>).<span style="color:#a6e22e">build</span>()), </span></span><span style="display:flex;"><span> Arguments.<span style="color:#a6e22e">of</span>(Device.<span style="color:#a6e22e">builder</span>().<span style="color:#a6e22e">deviceId</span>(2).<span style="color:#a6e22e">name</span>(<span style="color:#e6db74">&#34;Banana Pi&#34;</span>).<span style="color:#a6e22e">build</span>()) </span></span><span style="display:flex;"><span> ); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@ParameterizedTest</span> </span></span><span style="display:flex;"><span> <span style="color:#a6e22e">@MethodSource</span>(<span style="color:#e6db74">&#34;deviceArgs&#34;</span>) </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">storeDeviceTest</span>(Device device) { </span></span><span style="display:flex;"><span> deviceService.<span style="color:#a6e22e">storeDevice</span>(device); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p><code>streamDevices</code> serves the Arguments. This method must be <code>static</code>.</p> Catching the best prompt https://tty4.dev/development/catching-the-best-prompt/ Sat, 12 Aug 2023 02:00:00 -0100 https://tty4.dev/development/catching-the-best-prompt/ <p>Recently I had the idea to leverage generative AI and use it to generate random data for me. For that, I played around with the OpenAI API. Even when their pricing seems fair for me, I tried to find the best prompt to fit my needs without eating up my money as I&rsquo;d like to use the prompt very often.</p> <p>Finding a good prompt for a recurring task is a thing with a higher complexity than expected. A good prompt decides how good the results you get are. The challenge is to find concise and precise words. The german language sometimes tends to nested sentences. This pattern should be avoided when crafting prompts.</p> The five most useful commands for the docker cli https://tty4.dev/development/five-docker-commands/ Wed, 09 Aug 2023 02:00:00 -0100 https://tty4.dev/development/five-docker-commands/ <p>IMHO there are five docker commands which you need to have a successful start in containerized application development:</p> <p>Build an image of a Dockerfile:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker build -t IMAGE_NAME . </span></span></code></pre></div><p>Start a container for an image:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker run --name CONTAINER_NAME IMAGE_NAME </span></span></code></pre></div><p>Get and follow logs of the container.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker logs -f CONTAINER_NAME </span></span></code></pre></div><p>Execute a bash inside the container. Can be helpful for further introspection:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>docker exec -it CONTAINER_NAME bash </span></span></code></pre></div><p>Show all running containers.</p> Exploration of Wasm Workers Server https://tty4.dev/development/exploration-wws/ Wed, 02 Aug 2023 02:00:00 -0100 https://tty4.dev/development/exploration-wws/ <p>One direction towards which Webassembly (Wasm) is heading is the usage as serverless applications in the cloud or on the edge.</p> <p>The idea to do this is in my opinion great, because of few reasons. Naming some of them:</p> <ul> <li>Wasm modules have a minimal footprint.</li> <li>Wasm modules run in a sandbox and provide that way a security benefit out of the box.</li> <li>With one runtime you can run easily many code bases.</li> </ul> <h2 id="wasm-workers-server">Wasm Workers Server</h2> <p>VMware Wasm Labs spublished <a href="https://workers.wasmlabs.dev/">Wasm Workers Server</a> (WWS) which provides such an environment to run different code bases beside each other.</p> Wasm: SIMD operations https://tty4.dev/development/wasm-simd-operations/ Fri, 07 Jul 2023 02:00:00 -0100 https://tty4.dev/development/wasm-simd-operations/ <p>WebAssembly (Wasm) has support for <a href="https://tty4.dev/development/simd">SIMD</a>.</p> <p>There is a <a href="https://github.com/WebAssembly/simd/blob/master/proposals/simd/BinarySIMD.md">big instruction</a> set related to SIMD. This post covers some of them.</p> <h2 id="v128"><code>v128</code></h2> <p><code>v128</code> is the SIMD type for vectors. It is also the only one which is currently served by Wasm! So, when working with SIMD in Wasm this is the type used.</p> <p>That means that you can use 4 <code>32-bit</code> int values (or any other value that fills in). This is also called the <em>lane</em>.</p> Step by step towards wasm tables https://tty4.dev/development/wasm-tables/ Thu, 29 Jun 2023 02:00:00 -0100 https://tty4.dev/development/wasm-tables/ <p>Tables in Wasm can be used to store references to functions (= function pointers).</p> <p>In its core tables are arrays of references. These references can be accessed by index from Wasm code.</p> <h2 id="why-wasm-needs-tables">Why Wasm needs tables</h2> <p>Normally you can also call Wasm functions by the <code>call</code> instruction. But, this only works when the function is known at compile time.</p> <p>Tables can store function references at runtime. With that the function to be called can be determined at runtime.</p> Getting a higher confidence in spaCy similarity https://tty4.dev/development/better-similarities/ Sat, 24 Jun 2023 02:00:00 -0100 https://tty4.dev/development/better-similarities/ <p>That&rsquo;s a fast and small addendum to my recent post about similarity calculation of my blog posts. You can find part 1 <a href="https://tty4.dev/development/calculate-similarity-of-posts/">here</a>.</p> <p>I used spaCy to get the similarities between my posts, was unhappy with that.</p> <p>Well, the solution is far easier than I thought.</p> <p>After some research I found out that using another model leads to far better results!</p> <p>I used <code>en_core_web_lg</code> in conjunction with <a href="https://tfhub.dev/google/universal-sentence-encoder/4">universal-sentence-encoder</a>:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-py" data-lang="py"><span style="display:flex;"><span>nlp <span style="color:#f92672">=</span> spacy<span style="color:#f92672">.</span>load(<span style="color:#e6db74">&#34;en_core_web_lg&#34;</span>) </span></span><span style="display:flex;"><span>nlp<span style="color:#f92672">.</span>add_pipe(<span style="color:#e6db74">&#39;universal_sentence_encoder&#39;</span>) </span></span></code></pre></div><p>And this leads to really good results.</p> Calculate automatically the similarity between my posts https://tty4.dev/development/calculate-similarity-of-posts/ Wed, 21 Jun 2023 02:00:00 -0100 https://tty4.dev/development/calculate-similarity-of-posts/ <p>Keen readers may have recognized the box below every post. This shows you similar posts to the one you&rsquo;ve read and give you even more things to read.</p> <p>The box currently works as follow:</p> <ul> <li>Get the last 5 posts with the same tags, ordered by latest date.</li> <li>If no earlier posts with the same tags are available, show nothing.</li> </ul> <p>I don&rsquo;t really like the second case, because then it just shows you nothing. So why not use machine learning to calculate similar posts?</p> Wasm variable instructions https://tty4.dev/development/wasm-variable-instructions/ Sat, 17 Jun 2023 02:00:00 -0100 https://tty4.dev/development/wasm-variable-instructions/ <p>The everyday business in each programming language is the usage of variables. Wasm also has them. Here&rsquo;s how to use them.</p> <h2 id="the-scope-of-variables">The scope of variables</h2> <p>The scope of variables can be either <em>local</em> or <em>global</em>.</p> <p>If you are experienced in any higher language like JavaScript or Java, you may probably know what it means.</p> <h2 id="local-variables">Local variables</h2> <p><em>Local</em> variables have their scope in the functions body. They are referenced through the local indices in the function&rsquo;s body or their names.</p> One year of knowledge management: My switch to Trilium https://tty4.dev/no-category/knowledge-management-trilium/ Sat, 10 Jun 2023 10:00:00 -0100 https://tty4.dev/no-category/knowledge-management-trilium/ <p>It&rsquo;s been over a year since I last wrote about my knowledge management system. Since then, I&rsquo;ve made a significant change in the tool I use – I switched to <a href="https://github.com/zadam/trilium">Trilium</a>. This self-hosted desktop application has been a game changer for me in terms of usability and linking interrelated topics.</p> <p><img src="https://tty4.dev/trilium/image.png" alt=""></p> <h2 id="what-i-have-been-using-before">What I have been using before</h2> <p>Short recap: Before I switched to Trilium, I have been using <a href="https://foambubble.github.io/foam/">FoamBubbles</a> which acts as a VSCode Plugin (see my <a href="https://tty4.dev/no-category/building-knowledge-base/">post</a>).</p> Thoughts on event sourcing https://tty4.dev/development/ddd/thoughts-on-es/ Thu, 08 Jun 2023 10:00:00 -0100 https://tty4.dev/development/ddd/thoughts-on-es/ <p>In my recent posts I showed an approach on <a href="https://tty4.dev/development/ddd/event-sourcing-java-approach">how to implement event sourcing in Java</a>. During the implementation everything went as usual: I had the knowledge to start and build a mental model. And I had some resources to solve the first hurdles. The implementation went pretty good so far.</p> <p>But then.. things changed during writing the post. I realized that my application is a good <em>foundation</em> and shows the basics of event sourcing. But, beside of this a lot of questions appeared which weren&rsquo;t answered in the post.</p> Event sourcing in Java: First steps https://tty4.dev/development/ddd/event-sourcing-java-approach/ Wed, 31 May 2023 10:00:00 -0100 https://tty4.dev/development/ddd/event-sourcing-java-approach/ <p>This post belongs to a series about my <a href="https://tty4.dev/development/ddd/ddd-journey">DDD journey</a>.</p> <p>Check also: <a href="https://tty4.dev/development/ddd/event-sourcing">Concepts of Event Sourcing.</a></p> <p>In this post I will write up my approach to implement event sourcing in a Java application. This sample application aims to give a feeling about the DDD building blocks and which challenges in event sourcing are coming up.</p> <h2 id="the-service">The service</h2> <p>Let&rsquo;s assume that we shall build a service for a shop which contains clients and orders. As a first step we will build the service with the client model which applies event sourcing.</p> Calculate multiple data points in one instruction: SIMD https://tty4.dev/development/what-is-simd/ Mon, 22 May 2023 02:00:00 -0100 https://tty4.dev/development/what-is-simd/ <p>SIMD is short for <em>Single Instruction, Multiple Data</em>.</p> <p>In parallel computing you split your data and operate on every dataset at once.</p> <p><img src="https://tty4.dev/simd/simd-threads.drawio.png" alt=""></p> <p><em>SIMD</em> works different, as it is not using threads.</p> <p>SIMD uses many operating units and all of them execute the same operation at the same CPU cycle (= at the same time). That&rsquo;s where the name comes from: With a <em>single instruction</em> you operate on <em>multiple data</em>. And this is the reason, why it is so fast.</p> Comand-Query Responsibility Segregation (CQRS) https://tty4.dev/development/ddd/cqrs/ Wed, 17 May 2023 02:00:00 -0100 https://tty4.dev/development/ddd/cqrs/ <p>In DDD you will clearly come over the term &ldquo;Command and Query Responsibility Segregation&rdquo; or also: <em>CQRS</em>.</p> <p>This article describes this pattern and shows how it works together with <a href="https://tty4.dev/development/ddd/event-sourcing">Event Sourcing</a>.</p> <h2 id="the-problem">The problem</h2> <p>In an usual application you use the same data model for read and write operations in/from the database.</p> <p>This works good in simple applications, but can be messy in more complex applications. So data transfer objects (DTO) may be introduced to return a model that fits into the query.</p> Accessing and storing to memory in Wasm https://tty4.dev/development/wasm-memory/ Thu, 11 May 2023 02:00:00 -0100 https://tty4.dev/development/wasm-memory/ <p>Wasm has also a memory which helps you to store and access data at any point in your module.</p> <p>Memory can be created in the module itself or imported into the module. This post has a main focus on the first case, but will also introduce the latter case in the following section.</p> <h2 id="the-concept-of-memory">The concept of memory</h2> <p>In Wasm, the memory is linear. So from JavaScript perspective it is just a buffer of unsigned bytes from which you can read from and store into.</p> Released: Wasm-powered static search https://tty4.dev/no-category/static-search-released/ Fri, 05 May 2023 03:00:00 -0100 https://tty4.dev/no-category/static-search-released/ <p>I&rsquo;m thrilled to announce that I released the Wasm-powered static search, now.</p> <p>After integrating my index-generation service into Jenkins, I am now able to release new posts and automatically generate a new index on the fly!</p> <p>Every search is executed &amp; computed locally on client-side machines by using <a href="https://tty4.dev/tags/wasm/">Webassembly</a>.</p> <p>You can follow some of my thoughts and technical challenges during the implementation here:</p> <ul> <li><a href="https://tty4.dev/development/static-search/">A static search for my blog</a></li> <li><a href="https://tty4.dev/development/optimizing-wasm-js-size/">Optimizing Wasm and JS module size and load time. </a></li> <li><a href="https://tty4.dev/development/fp-java-idea/">Experiencing functional programming in Java </a></li> </ul> Dive into Wasm: Control flow instructions https://tty4.dev/development/wasm-control-flow/ Thu, 04 May 2023 03:00:00 -0100 https://tty4.dev/development/wasm-control-flow/ <p>Wasm provides ways to control the flow of the code. This influences the way which results and which behavior a Wasm module shows.</p> <p>This post gives a quick glance at the instructions to control the flow and shows their usage with WAT examples.</p> <h2 id="the-unreachable">The <code>unreachable</code></h2> <p>The <code>unreachable</code> instruction marks a code part which should be unreachable. This leads to a trap and stops the execution of the module.</p> <p>The following code leads to a trap.</p> A static search for my blog https://tty4.dev/development/static-search/ Sun, 30 Apr 2023 10:00:00 -0100 https://tty4.dev/development/static-search/ <p>More than once I&rsquo;ve been thinking about a static search for this blog.</p> <p>This site is using <a href="https://gohugo.io">Hugo</a> as a site generator. There are some <a href="https://gohugo.io/tools/search/">search solutions</a> for Hugo sites, but I thought it would be a fun project to work on and create a solution for my own.</p> <p>So I split the problem up in three parts:</p> <ol> <li>Create a JSON-representation of my blog.</li> <li>Create an index out of this json representation.</li> <li>Search the index on the client-side.</li> </ol> <div class="mermaid">flowchart LR subgraph js['Site generator'] direction TB Blog(Page content) Blog --> Hugo Hugo -->|generate| JSON1(page.json) end subgraph ig ['Index generator'] IG[Index Generator] JSON1 --> IG IG -->|generate| IDX(index.json) end subgraph se['Search engine'] IDX --> SE[Search Engine] Terms(Search terms) --> SE SE --> |output| Res(Results) end UI --> Terms </div> <p>The following sections are about the implementation and give insight to my thoughts.</p> Dive into Wasm: Functions https://tty4.dev/development/wasm-functions/ Thu, 20 Apr 2023 03:00:00 -0100 https://tty4.dev/development/wasm-functions/ <p>Functions are one of the main building blocks of Wasm. In the following sections I discover how to use them and how they are built.</p> <h2 id="the-first-function">The first function</h2> <p>WAT code is represented as functions in this syntax:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>( <span style="color:#66d9ef">func</span> <span style="color:#f92672">&lt;</span>signature<span style="color:#f92672">&gt;</span> <span style="color:#f92672">&lt;</span>locals<span style="color:#f92672">&gt;</span> <span style="color:#f92672">&lt;</span>body<span style="color:#f92672">&gt;</span> ) </span></span></code></pre></div><ul> <li>The <em>signature</em> declares the input parameters and the return values.</li> <li>The <em>locals</em> are variables.</li> <li>The <em>body</em> is a list of low-level instructions.</li> </ul> <p><a href="https://webassembly.github.io/spec/core/syntax/modules.html#syntax-func">Here</a> is the syntax definition.</p> <p>This function takes two 32-bit params and results one 64-bit float:</p> Writing Wasm: modules https://tty4.dev/development/wasm-modules/ Sun, 16 Apr 2023 02:00:00 -0100 https://tty4.dev/development/wasm-modules/ <p>The most simple Wasm module doesn&rsquo;t need much code. This post describes the definition of it, and how the resulting binary code looks like. It shall give the basis for further WAT-styled code.</p> <h2 id="pre-requisites">Pre-requisites</h2> <p>Before you start to write Wasm modules, you need some tooling.</p> <p>So, install <a href="https://github.com/WebAssembly/wabt">wabt</a> first. This includes <code>wat2wasm</code> and allows you to compile <code>.wat</code> files to <code>.wasm</code> with the following command:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>wat2wasm sample.wat </span></span></code></pre></div><p>With that you&rsquo;ll get the Wasm binary with the <code>.wasm</code> ending.</p> Experiencing functional programming in Java https://tty4.dev/development/fp-java-idea/ Sun, 02 Apr 2023 01:00:00 -0100 https://tty4.dev/development/fp-java-idea/ <p>In the recent days I&rsquo;ve been working on my <a href="https://tty4.dev/development/fp-java">Functional Programming</a> skills in Java.</p> <p>Reading about it and implementing small functions makes it easy to understand the basics. But it&rsquo;s always better to have hands-on experience.</p> <p>So I gave myself the task to implement a service which creates a simple search index for this blog.</p> <h2 id="the-idea">The idea</h2> <p>The core idea is to realize the following flow:</p> <div class="mermaid">flowchart TD; PP(Pre process) TK(Tokenize) Syn(Add synonyms) Idx(Add to index) subgraph Aggregate PP --> |Processed page| TK --> |Tokenized page| Syn --> |Page with synonyms| Idx end Trigger --> |Page| PP Aggregate --> Index </div> <p>As you can see, this is already a pipe which can be realized through the chaining of functions:</p> What is eBPF? https://tty4.dev/development/what-is-ebpf/ Thu, 23 Mar 2023 02:00:00 -0100 https://tty4.dev/development/what-is-ebpf/ <p>In the cloud landscape there is currently one technology, that was raising questions to me: <a href="https://ebpf.io/"><code>eBPF</code></a>.</p> <p>I want to give a short answer what <code>eBPF</code> is and how it is used for Cloud Native development.</p> <p><code>eBPF</code> is not a &lsquo;fresh and new&rsquo; idea from yesterday. In fact, it exists since 2014, but has risen more and more attention in the past years. It is often referred to as &lsquo;JS, but for Kernel programmers&rsquo;.</p> Functional Programming in Java https://tty4.dev/development/fp-java/ Sun, 12 Mar 2023 02:00:00 -0100 https://tty4.dev/development/fp-java/ <p>Functional programming can be achieved in Java, though it needs a lot of discipline to not mix things up. This post discusses the different ways of doing things in a functional way in Java.</p> <p>When you know the basics of functional programming and want to start with that style in Java, you should keep the following interfaces in your mind:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Supplier () -&gt; x </span></span><span style="display:flex;"><span>Consumer x -&gt; () </span></span><span style="display:flex;"><span>BiConsumer x, y -&gt; () </span></span><span style="display:flex;"><span>Callable () -&gt; x throws ex </span></span><span style="display:flex;"><span>Runnable () -&gt; () </span></span><span style="display:flex;"><span>Function x -&gt; y </span></span><span style="display:flex;"><span>BiFunction x,y -&gt; z </span></span><span style="display:flex;"><span>Predicate x -&gt; boolean </span></span><span style="display:flex;"><span>UnaryOperator x1 -&gt; x2 </span></span><span style="display:flex;"><span>BinaryOperator x1,x2 -&gt; x3 </span></span></code></pre></div><p>(<a href="https://stackoverflow.com/questions/29945627/java-8-lambda-void-argument">List from stackoverflow.com</a>)</p> The shift of thinking: Imperative vs. declarative programming https://tty4.dev/development/fp-imp-vs-decl/ Sat, 04 Mar 2023 02:00:00 -0100 https://tty4.dev/development/fp-imp-vs-decl/ <p>A key characteristic of functional programming is the declarative way of describing how software shall behave.</p> <p>In contrast to that stands the imperative style, where you give step-by-step instructions what the program shall do.</p> <h2 id="von-neumann-architecture">Von Neumann Architecture</h2> <p>The reason why the imperative style lasts so long and is so old, lays in the way how computers work.</p> <p>The basis of our computers til today is the <a href="https://en.wikipedia.org/wiki/Von_Neumann_architecture">von Neumann architecture</a>.</p> <p>In the von Neumann architecture the computer gets instructions which tell it how it should work. So the algorithm is <em>imperative</em> and tells which data should be loaded and which instruction shall be executed.</p> Optimizing Wasm and JS module size and load time. https://tty4.dev/development/optimizing-wasm-js-size/ Thu, 23 Feb 2023 02:00:00 -0100 https://tty4.dev/development/optimizing-wasm-js-size/ <p>Recently I&rsquo;ve thought of a static search for this blog without the need to run a backend.</p> <p>So I started to build the following &lsquo;search engine&rsquo;:</p> <p><img src="https://tty4.dev/wasm/search/project-glue.svg" alt=""></p> <p>I don&rsquo;t know until now if I will deploy this anytime, but it&rsquo;s a good project to make use of a little bit functional programming, Rust and Wasm.</p> <p>However, one problem I faced was the size of the Wasm module and JS overhead for the search.</p> Wasm: A technical view https://tty4.dev/development/wasm-technical-view/ Tue, 14 Feb 2023 02:00:00 -0100 https://tty4.dev/development/wasm-technical-view/ <p><a href="https://webassembly.org">WebAssembly</a> is one of the most recent technologies of the web and stands for itself in the browser. Historically it is an successor of <a href="http://asmjs.org/">asm.js</a>.</p> <p>When supported, code which is written in C, C++, Rust or any other language can be compiled into Wasm bytecode (= <code>.wasm</code> file) and loaded into the JS page and executed in there (<a href="https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/instantiateStreaming">source</a>):</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">importObject</span> <span style="color:#f92672">=</span> { <span style="color:#a6e22e">imports</span><span style="color:#f92672">:</span> { <span style="color:#a6e22e">imported_func</span><span style="color:#f92672">:</span> (<span style="color:#a6e22e">arg</span>) =&gt; <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">arg</span>) } }; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#a6e22e">WebAssembly</span>.<span style="color:#a6e22e">instantiateStreaming</span>(<span style="color:#a6e22e">fetch</span>(<span style="color:#e6db74">&#34;simple.wasm&#34;</span>), <span style="color:#a6e22e">importObject</span>).<span style="color:#a6e22e">then</span>( </span></span><span style="display:flex;"><span> (<span style="color:#a6e22e">obj</span>) =&gt; <span style="color:#a6e22e">obj</span>.<span style="color:#a6e22e">instance</span>.<span style="color:#a6e22e">exports</span>.<span style="color:#a6e22e">exported_func</span>() </span></span><span style="display:flex;"><span>); </span></span></code></pre></div><p>The execution happens inside an own runtime. Currently every major browser supports Wasm.</p> Ways to compile from Rust to Wasm/WASI https://tty4.dev/development/rust-wasm-compilation/ Wed, 08 Feb 2023 12:00:00 -0100 https://tty4.dev/development/rust-wasm-compilation/ <p>When you follow tutorials for Rust and Wasm, you&rsquo;ll find different ways of how to compile your code to a <code>.wasm</code> file.</p> <p>To untangle the confusion this post shows the ways and what the differences are.</p> <p>This tutorial follows especially the <code>wasm32-wasi</code> target, but gives also insights to the <code>wasm</code> section.</p> <h2 id="1-using-the-rustc-compiler">1. Using the rustc compiler</h2> <p>If you want to compile one file (e.g. projects that are not libs), you can use the compiler directly:</p> Hexagonal architecture: Delaying decisions https://tty4.dev/architecture/hexagonal-architecture-delaying-decisions/ Thu, 02 Feb 2023 08:00:00 -0100 https://tty4.dev/architecture/hexagonal-architecture-delaying-decisions/ <p>One fundamental concept of the <a href="https://tty4.dev/development/ddd/hexagonal-architecture">hexagonal architecture</a> is the isolation of different layers from each other. This is realized by the communication via interfaces and appliance of <em>dependency inversion</em>.</p> <p>Exactly this characteristic makes it possible to <em>delay decisions</em> in regards of technical dependencies. Lets see how.</p> <h2 id="making-use-of-abstractions">Making use of abstractions</h2> <p>In the hexagonal architecture, the application core defines the ports for the infrastructure and UI layers via the concept of interfaces. The core itself contains the business and domain logic.</p> The hexagonal architecture https://tty4.dev/development/ddd/hexagonal-architecture/ Fri, 27 Jan 2023 10:00:00 -0100 https://tty4.dev/development/ddd/hexagonal-architecture/ <p>Using the hexagonal architecture for more complex projects gives more and better abstraction layers. This is an introduction into the ports and adapters (or: hexagonal architecture) and how it interplays with Domain Driven Design.</p> <p>Many very good things are written in the web about the hexagonal architecture, so I&rsquo;ll only cover things which are important in the context of Domain Driven Design.</p> <h2 id="why-hexagonal-architecture">Why hexagonal architecture?</h2> <p>There are different architecture styles for services like the layered architecture as an example for the simplest one.</p> Creating an own WASI function https://tty4.dev/development/wasi-load-fd-write/ Thu, 19 Jan 2023 02:00:00 -0100 https://tty4.dev/development/wasi-load-fd-write/ <p>One of the core concepts of WASI is to make the execution of Wasm code portable. This means: Every WASI runtime needs to implement the WASI specification and serve the needed methods for the Wasm module.</p> <p>When you followed along my post about <a href="https://tty4.dev/development/wasi-rust">the implementation of WASI in Rust</a> you might have seen the following import of the <code>fd_write</code> function in the compiled Wasm module:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>(import <span style="color:#e6db74">&#34;wasi_snapshot_preview1&#34;</span> <span style="color:#e6db74">&#34;fd_write&#34;</span> (<span style="color:#a6e22e">func</span> (;<span style="color:#ae81ff">0</span>;) (type <span style="color:#ae81ff">10</span>))) </span></span></code></pre></div><p>The function <code>fd_write</code> will be imported from the <code>wasi_snapshot_preview1</code> module and needs implement the interface which is defined as <code>type 10</code>.</p> Under the surface of WASI in Rust https://tty4.dev/development/wasi-rust/ Wed, 11 Jan 2023 02:00:00 -0100 https://tty4.dev/development/wasi-rust/ <p>In the recent years <a href="https://webassembly.org/">WebAssembly</a> (Wasm) got more and more popular: For different codebases you have one runtime in the web. So you can bring your C or Rust code into the web browser!</p> <p>Few years ago WebAssembly broke out of the web and started to aim the system as a runtime environment. With the <a href="https://wasi.dev/"><em>WebAssembly System Interface</em></a> you can run WebAssembly directly on the machine - no browser needed. This enables a wider range of possibilities.</p> Java, Cloud, IoT Trends in 2023 https://tty4.dev/no-category/trends-2023/ Tue, 03 Jan 2023 02:00:00 -0100 https://tty4.dev/no-category/trends-2023/ <p>I hope you all had a good start into the new year! 2023 is just a few days old and it is not only time to look at the things that happened in the past year. Here I want to give insights on to the trends which I think Cloud developers should keep an eye on. As my experience mainly lays in the cloud, java and IoT area, this is the part at which I&rsquo;ll focus on here.</p> Behind containerized applications https://tty4.dev/development/behind-containerized-applications/ Tue, 27 Dec 2022 02:00:00 -0100 https://tty4.dev/development/behind-containerized-applications/ <p>When you work with containerized applications you have probably written a <code>Dockerfile</code>, built and run it.</p> <p>Maybe you&rsquo;ve started with a base image like <a href="https://hub.docker.com/_/alpine"><em>Alpine Linux</em></a> to have a small basis to run your application. When you check the <a href="https://github.com/alpinelinux/docker-alpine/blob/a791ed3b042cb15f4dda594dd2fb088dcb725542/x86_64/Dockerfile"><code>Dockerfile</code> of the alpine image</a> you&rsquo;ll see that the alpine image bases on another image called <code>scratch</code>:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dockerfile" data-lang="dockerfile"><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span><span style="color:#e6db74"> scratch</span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ADD</span> alpine-minirootfs-3.17.0-x86_64.tar.gz /<span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">CMD</span> [<span style="color:#e6db74">&#34;/bin/sh&#34;</span>]<span style="color:#960050;background-color:#1e0010"> </span></span></span></code></pre></div><p><code>scratch</code> is the most minimal image in the docker world and serves a starting point for base images. You are not able to pull, run or tag an image with <code>scratch</code>, but you can use it in a Dockerfile.</p> Concepts of event sourcing https://tty4.dev/development/ddd/event-sourcing/ Sun, 18 Dec 2022 10:00:00 -0100 https://tty4.dev/development/ddd/event-sourcing/ <p>This post belongs to a series about my <a href="https://tty4.dev/development/ddd/ddd-journey">DDD journey</a>.</p> <p>Event sourcing is a pattern which interacts very well with DDD and creates something like a log book of your application state. This helps you to recreate your app state every time when needed. This post will introduce you to this topic and show the challenges in this pattern.</p> <p>The idea behind event sourcing is, that every change of the state in an application is captured in an event object. These events are stored in an <em>append-only</em> database and read by the application when a recreation is needed.</p> The key points of Domain Driven Design https://tty4.dev/development/ddd/ddd-keypoints/ Fri, 16 Dec 2022 12:00:00 -0100 https://tty4.dev/development/ddd/ddd-keypoints/ <p>This is the first post in the <a href="https://tty4.dev/development/ddd/ddd-journey">DDD journey</a>.</p> <p>In this post I&rsquo;ll show the definitions and concepts of Domain Driven Design.</p> <p>As the name <em>Domain Driven Design</em> states, the design of the application is all about the Domain. Maybe you have read the book &lsquo;Problem Frames&rsquo; by Michael Jackson (no, not this Michael). He states:</p> <blockquote> <p>It is more helpful &hellip; to recognize that the solution is located in the computer and its software, and the problem is in the world outside. &hellip;</p> The Domain Driven Design Journey https://tty4.dev/development/ddd/ddd-journey/ Thu, 15 Dec 2022 10:00:00 -0100 https://tty4.dev/development/ddd/ddd-journey/ <p>Domain Driven Design (DDD) is an software engineering approach, which interplays well with microservices. It helps a lot to build and design application in accordance to the domain where it shall solve problems.</p> <p>The concepts of DDD are at first theoretical, but can be easily and fast introduced in practice. But where to start?</p> <p>This post series will explain the concepts of DDD and show a sample implementation. The series will cover the following topics and links will be added as soon as a new post appears.</p> Bash script for automatic Hugo site updates https://tty4.dev/no-category/hugo-site-upgrade-script/ Tue, 29 Nov 2022 10:00:00 -0100 https://tty4.dev/no-category/hugo-site-upgrade-script/ <p>On the bottom of this page you can see that this page is generated by <a href="https://gohugo.io/">hugo</a>.</p> <p>After nearly one year of blogging I finally invested some time to write a bash script which updates this blog automatically.</p> <p>Although I think that scripts can be a little bit useless, when you don&rsquo;t have exactly the same repository setup, you may want to adapt it. You can use it in a pipeline, after a commit hook or even manually!</p> Testcontainers revisited: Managing the lifecycle of the database https://tty4.dev/development/2022-11-25-testcontainers-revisited/ Mon, 28 Nov 2022 02:00:00 -0100 https://tty4.dev/development/2022-11-25-testcontainers-revisited/ <div class="alert-low"> <p>I created a follow-up for <strong>Spring Boot 3.1</strong>. Check it <a href="https://tty4.dev/development/2023-08-18-testcontainers-spring-boot-3/">here</a></p> <p>Even when things changed, the concept of Testcontainers is the same and you can use it also in the way it is described here.</p> </div> <p>Few weeks ago I was <a href="https://tty4.dev/development/testcontainers-simple-example">taking a look at Testcontainers</a>.</p> <p>Two questions arrived:</p> <ol> <li>How to keep the database connection open and reuse it.</li> <li>Clean up the database between tests.</li> </ol> <p>The post was Spring Boot specific, but here I&rsquo;ll also have a look at plain Java projects.</p> The skill radar: A better way to visualize and classify your knowledge https://tty4.dev/no-category/skill-radar/ Tue, 22 Nov 2022 02:00:00 -0100 https://tty4.dev/no-category/skill-radar/ <p><em>tl;dr:</em> <a href="https://github.com/denniskawurek/skill-radar">Build your own skill radar with this code from Github.</a></p> <p>When you&rsquo;re building a portfolio you may want to show which skills you have.</p> <p>My <a href="https://dkwr.de">site</a> exists since ~2016 and I never found a way which makes me happy enough to show what I can. A list of skills just never made me happy, though I&rsquo;m using it til now. But: This makes it look like a lot of buzz words which don&rsquo;t show how much experience I have and how confident I feel in the technologies.</p> Timescaledb: Insert data into a compressed chunk https://tty4.dev/development/insert-compressed-chunk-timescaledb/ Fri, 18 Nov 2022 02:00:00 -0100 https://tty4.dev/development/insert-compressed-chunk-timescaledb/ <p>When you want to add an entry into your timescale database, you may get the following error messages:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>ERROR: insert into a compressed chunk that has primary <span style="color:#f92672">or</span> unique constraint is <span style="color:#f92672">not</span> supported </span></span></code></pre></div><p>or:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>ERROR: insert with ON CONFLICT or RETURNING clause is not supported on compressed chunks </span></span></code></pre></div><p>If you check the <a href="https://docs.timescale.com/api/latest/compression/">documentation</a> you see that <code>ON CONFLICT</code> and <code>RETURNING</code> statements and <code>PRIMARY KEY</code>s are not supported on compressed chunks.</p> <p>There are also two issues on GitHub for this (<a href="https://github.com/timescale/timescaledb/issues/3323">#3323</a>, <a href="https://github.com/timescale/timescaledb/issues/4113">#4113</a>) which discuss this topic.</p> Notes I made during reading Clean Code by Robert C. Martin https://tty4.dev/development/clean-code-notes/ Wed, 16 Nov 2022 02:00:00 -0100 https://tty4.dev/development/clean-code-notes/ <p>Not so many books are recommended by so many generations of software developers as <em>Clean Code</em> by Robert C. Martin. And after reading it I can just agree on this.</p> <p>This book can make you a better developer or if you already have professional experience give you advices to strengthen and encourage your existing techniques.</p> <p>Some of the things written down may seem outdated or you may not agree on them (which is also the intention of the author), but it will give you a guide and frame for coding on which I think every developer will agree.</p> Using Testcontainers in a Spring Boot application with MariaDB https://tty4.dev/development/testcontainers-simple-example/ Sun, 13 Nov 2022 09:00:00 -0100 https://tty4.dev/development/testcontainers-simple-example/ <div class="alert-low"> <p>I created a follow-up for <strong>Spring Boot 3.1</strong>. Check it <a href="https://tty4.dev/development/2023-08-18-testcontainers-spring-boot-3/">here</a></p> <p>Even when things changed, the concept of Testcontainers is the same and you can use it also in the way it is described here.</p> </div> <p>When writing integration tests for a service one of the problems which need to be attacked is the database: You want to assure that an entry is really stored in the database.</p> <p>For that there are multiple ways, like using a test instance of a database, using a deployed database and use a prefix for all data for later deletion, a local database or an in-memory database like H2.</p> Review: Code by Charles Petzold https://tty4.dev/development/code-charles-petzold-review/ Mon, 07 Nov 2022 09:00:00 -0100 https://tty4.dev/development/code-charles-petzold-review/ <p><em>Code</em> by Charles Petzold provides a compact bottom to top overview of how computers really work. And what technically the difference between hardware and software is.</p> <p>Petzold starts with some real life examples and adapts them to our computers. After this introduction electrical circuits are build to a working CPU with an ALU and memory. And within this you&rsquo;ll see <em>how</em> they are really working and bound together!</p> <p>Furthermore there is also a chapter to my beloved topic of clocks!</p> How to use Mockito to test the behavior of a Java application - in a nutshell https://tty4.dev/development/mockito-unit-testing-nutshell/ Mon, 24 Oct 2022 02:00:00 -0100 https://tty4.dev/development/mockito-unit-testing-nutshell/ <p><a href="https://site.mockito.org/">Mockito</a> is a really powerful tool. And even more: It&rsquo;s documentation and logs are so good, that you don&rsquo;t need to look at the documentation if you&rsquo;re misusing it! Here I&rsquo;ll show some of the common functions I&rsquo;m using with a small example.</p> <h2 id="example-application">Example application</h2> <p>I&rsquo;ll show you an example application, which I&rsquo;ll use within the next sections. The example may not to seem so logical, but it will show you the most important things.</p> Implementation of an external authorizer for Istio in Java https://tty4.dev/development/ext-authz-java/ Tue, 18 Oct 2022 09:00:00 -0100 https://tty4.dev/development/ext-authz-java/ <p>In my last posts I was writing about using an external authorizer for Envoy to use Istio to authorize requests (check <a href="https://tty4.dev/development/istio-as-authorization-part-1/">part 1</a> and <a href="https://tty4.dev/development/istio-as-authorization-part-2/">part 2</a>).</p> <p>In part 2 I wrote that I will also show an example of the authorization service in Java. Here is it.</p> <h2 id="code-example">Code example</h2> <p><a href="https://github.com/denniskawurek/java-ext-authz">Full code example available at GitHub</a>.</p> <p>You can see the full code example with a Dockerfile in my repository. The following subsections explain you to it step-by-step. This project uses <a href="https://github.com/grpc/grpc-java">grpc-java</a> for the server.</p> Using Istio as an external authorizer. Part 2: The implementation https://tty4.dev/development/istio-as-authorization-part-2/ Sun, 16 Oct 2022 09:00:00 -0100 https://tty4.dev/development/istio-as-authorization-part-2/ <p>This is the second part of a series about using Istio as an external authorizer. <a href="https://tty4.dev/development/istio-as-authorization-part-1"><strong>Here&rsquo;s part 1.</strong></a></p> <h2 id="prerequisite">Prerequisite</h2> <p>To follow and understand this guide you need the following prerequisites:</p> <ol> <li>Read and understand the authorization concepts of Istio.</li> <li><strong>Important:</strong> Setup your local cluster accordingly to <a href="https://tty4.dev/development/spring-boot-istio-minikube">this guide</a>, as I&rsquo;ll use the application as an example.</li> </ol> <h2 id="the-external-authorizer">The external authorizer</h2> <p>The external authorizer needs to implement the <a href="https://github.com/envoyproxy/envoy/blob/main/api/envoy/service/auth/v3/external_auth.proto">Protobuf interface defined by Envoy</a>.</p> <p>I&rsquo;ll write more of the implementation of it as a Java service in another post, but let&rsquo;s use the <a href="https://github.com/istio/istio/tree/release-1.15/samples/extauthz">sample application</a> by Istio.</p> Using Istio as an external authorizer. Part 1: The theory https://tty4.dev/development/istio-as-authorization-part-1/ Sun, 16 Oct 2022 08:00:00 -0100 https://tty4.dev/development/istio-as-authorization-part-1/ <p>This is the second part of a series about using Istio as an external authorizer. <a href="https://tty4.dev/development/istio-as-authorization-part-2"><strong>Here&rsquo;s part 2.</strong></a></p> <p>Authorization to applications is one of the most security critical parts of a development process. Every public available service needs it.</p> <p>But, in a microservice architecture most of the time the authorization doesn&rsquo;t belong to the business logic of a service. For sure there are many ways to implement it, but the best thing is to implement it once for all. This can be done via a library or middleware.</p> Using an Istio gateway to access a Spring Boot application in minikube https://tty4.dev/development/spring-boot-istio-minikube/ Tue, 11 Oct 2022 09:00:00 -0100 https://tty4.dev/development/spring-boot-istio-minikube/ <p>In the last days I was trying to run and experiment with Istio. I followed the <a href="https://istio.io/latest/docs/setup/getting-started/">getting started</a> guide by Istio itself, but I couldn&rsquo;t make it run with kind. I followed some guides, but I didn&rsquo;t want to install explicitly an nginx ingress, because I like it when things are as lightweight as possible when I&rsquo;m learning new stuff.</p> <p>So here&rsquo;s a guide how to run a Spring Boot application and access it through an Istio Gateway.</p> Building and running a Docker container for a Java application https://tty4.dev/development/java-app-docker-locally/ Sat, 24 Sep 2022 09:00:00 -0100 https://tty4.dev/development/java-app-docker-locally/ <p>There are different ways to build a Docker image locally of your Java application and start a container.</p> <p>This one is more of a step-by-step guide, which can also be automated by a local script. If you want you can also move the build steps into the Dockerfile, if it doesn&rsquo;t give you any conflicts in a pipeline.</p> <h2 id="the-dockerfile">The Dockerfile</h2> <p>First, create a <code>Dockerfile</code> in the root of your project. Consider to choose the right JDK version for your project.</p> Use a locally built Docker image in kind https://tty4.dev/development/use-local-docker-image-kind/ Sat, 24 Sep 2022 09:00:00 -0100 https://tty4.dev/development/use-local-docker-image-kind/ <p>If you create a local cluster with <a href="https://kind.sigs.k8s.io">kind</a> and try to use a locally built Docker image in one of your Pods, you&rsquo;ll probably face the issue that this image cannot be found!</p> <p>Well, the problem is that kind on one side looks after the image at the official Docker repositories and on the other side doesn&rsquo;t serve a local registry out of the box, like minikube for example does.</p> <p>You can <a href="https://kind.sigs.k8s.io/docs/user/local-registry">create a local registry</a> when you create your cluster, but this may not work on Windows or without any problems.</p> A story about Docker, failed builds and package locks https://tty4.dev/development/story-docker-builds-package-locks/ Wed, 14 Sep 2022 10:00:00 +0000 https://tty4.dev/development/story-docker-builds-package-locks/ <p>Recently I faced an issue where a docker build failed. The content of the Dockerfile was something like this:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Dockerfile" data-lang="Dockerfile"><span style="display:flex;"><span><span style="color:#66d9ef">FROM</span><span style="color:#e6db74"> node:16-alpine as BUILDER</span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">WORKDIR</span><span style="color:#e6db74"> /usr/app</span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#75715e"># COPY statements of the /src directory to /usr/app</span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> npm ci --only<span style="color:#f92672">=</span>prod<span style="color:#960050;background-color:#1e0010"> </span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> npm run build<span style="color:#960050;background-color:#1e0010"> </span></span></span></code></pre></div><p>Running the <code>npm i</code> and <code>npm run build</code> commands were working perfect when executed in my local CLI. In the Dockerfile the problem threw some <code>tsc</code> errors saying that there are incompatible types.</p> The day I called Microsoft Support https://tty4.dev/no-category/the-day-i-called-microsoft-support/ Fri, 02 Sep 2022 02:00:00 -0100 https://tty4.dev/no-category/the-day-i-called-microsoft-support/ <p>The first computer I got was a desktop PC by HP in the year 2003. It was running Windows XP and introduced me into the world of computers.</p> <p>I was just 10 years old, and I had a fantastic time diving into various games and tinkering with computer-specific settings. Many people liked Win XP. I even know people who work with clients that continue to run their businesses on machines equipped with this age-old software. Luckily not connected to the internet!</p> Review: Designing Data-Intensive Applications by Martin Kleppmann https://tty4.dev/development/data-intensive-applications/ Fri, 26 Aug 2022 09:00:00 -0100 https://tty4.dev/development/data-intensive-applications/ <p>Short version: If you are maintaining, touching, planning, developing or interested in systems which are working with a <em>lot</em> of data, then read this book.</p> <p>It gives on one side a good overview of the best practices, tools, concepts and scientific work in this field and goes in-depth to the most-important topics, so that you can understand them good enough for decision finding.</p> <p>I think everyone from the group of people I mentioned in the first paragraph should have a copy of it and keep it as a reference book. Even if it doesn&rsquo;t go deep enough for you, you can take a look at the bunch of references at the end of every chapter.</p> The biggest change ever made https://tty4.dev/development/biggest-change-ever-made/ Thu, 25 Aug 2022 09:00:00 -0100 https://tty4.dev/development/biggest-change-ever-made/ <p>Let me tell you the story of the biggest change I&rsquo;ve ever made in my current career and how I would do it better today.</p> <p>In a project I worked we had three classes like the following one:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Book</span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> bookId; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> bookshelfId; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> title; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">Book</span>(<span style="color:#66d9ef">int</span> bookId, <span style="color:#66d9ef">int</span> bookshelfId, String title) { </span></span><span style="display:flex;"><span> <span style="color:#75715e">// more code here ...</span> </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> <span style="color:#75715e">// Getter and setter</span> </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>However one day, we needed to change the <code>bookshelfId</code> parameter to a reference of a new introduced class named <code>Bookshelf</code>.</p> CI/CD pipelines as a documentation of the build process https://tty4.dev/development/ci-cd-pipelines-as-documentation/ Wed, 24 Aug 2022 09:00:00 -0100 https://tty4.dev/development/ci-cd-pipelines-as-documentation/ <p>CI/CD Pipelines don&rsquo;t only exist to build and deploy projects automatically without any obstacles and loss of time, they also assure the quality of a project.</p> <p>So beside a build process pipelines can execute tests, linters or fitness functions to assure architectural quality. And even more!</p> <p>Recently I was working on a project and thought about how great it is to have the build process documented in the pipeline side-by-side in the code.</p> Using go-templates to get insights into a Kubernetes cluster https://tty4.dev/development/kubernetes-go-templates/ Fri, 12 Aug 2022 09:00:00 -0100 https://tty4.dev/development/kubernetes-go-templates/ <p>Sometimes you need information of your cluster state or properties and need to iterate through many resources like all deployments or so.</p> <p>You can use <a href="https://tty4.dev/development/kubernetes-tools/">different tools to get an insight</a>.</p> <p>But beside of hoping that the tool has the correct plugin or feature, there is also a more &rsquo;elegant&rsquo; way for this. Elegant means in this context: Customized to your needs.</p> <h2 id="using-go-templates-to-retrieve-information">Using go-templates to retrieve information</h2> <p>With go-templates you can use your <code>kubectl</code> output to show it in a way you like. You can think of a filtering out properties on conditions or show them in a formatted way. Let&rsquo;s check an example.</p> azsecd: High memory consumption on Azure AKS cluster node https://tty4.dev/development/azure/azsecd-aks-high-memory-consumption/ Wed, 10 Aug 2022 09:00:00 -0100 https://tty4.dev/development/azure/azsecd-aks-high-memory-consumption/ <p>Recently the monitoring fired some alarms due to a high memory consumption in the production cluster.</p> <p>A look into the monitoring, revealed that at least all Pods behaved normally and without any unexpected loads. So why the alarm?</p> <p>Well, investigating further with the <code>kubectl node-shell</code> command I saw that a process called <code>azsecd</code> was using nearly 60% (!) of the node memory.</p> <p>A look into the syslogs with the following command gave more information:</p> Using DBRider for a clean state between JUnit tests https://tty4.dev/development/dbrider-for-clean-state-between-tests/ Fri, 05 Aug 2022 09:00:00 -0100 https://tty4.dev/development/dbrider-for-clean-state-between-tests/ <p>Whenever you write Java/Spring Boot tests which are using database access (e.g. when running a <code>@SpringBootTest</code>), you should clean up the database to have a clean state between your tests.</p> <p>In fact, this is not a trivial task as some of these problems can appear:</p> <ul> <li>You may need to check that you don&rsquo;t insert or delete data between tests and provoke Unique Key or Foreign Key exceptions.</li> <li>You may tear down and set up the database between test runs.</li> <li>You could tend to define an order of test runs which works. But this is not good as this creates a &lsquo;happy path&rsquo; for your tests.</li> <li>You may tend to insert data always with already set primary keys. These primary keys are not allowed to be used by other tests. That&rsquo;s not good as you need the knowledge of all these primary keys.</li> </ul> <p>But that&rsquo;s not good! When you test the behavior of your application you should not implement extra database checks to make sure that before and after your test you have a good state of the database.</p> Tools to manage Kubernetes resources https://tty4.dev/development/kubernetes-tools/ Fri, 29 Jul 2022 02:00:00 -0100 https://tty4.dev/development/kubernetes-tools/ <p>There are quite a lot of tools to view and manage your Kubernetes resources. I tried some of them and want to give you a small insight into what I think is the best way to view, update, delete and check resources of your Kubernetes cluster.</p> <h2 id="kubectl">kubectl</h2> <p>With <a href="https://kubernetes.io/docs/reference/kubectl/">kubectl</a> you&rsquo;ll get a tool directly by the makers of Kubernetes.</p> <p>I think that you don&rsquo;t need to use it mandatory all the time, as the other tools I&rsquo;ll present you here will make your workflows faster. But I think that knowing how to use kubectl will give you more flexibility: You&rsquo;ll always know which commands you&rsquo;re firing and what they do. Your knowledge in regards of a Kubernetes cluster will be enhanced and last but not least: When you update your Kubernetes cluster and kubectl, you can be sure, that you&rsquo;ll be always up-to-date and can use the latest features.</p> Docker images as compilers https://tty4.dev/development/docker-images-as-compilers/ Mon, 25 Jul 2022 02:00:00 -0100 https://tty4.dev/development/docker-images-as-compilers/ <p>Today I saw a blog post about <a href="https://matt-rickard.com/non-obvious-docker-uses/">non-obvious Docker uses</a>. And one of them states to use Docker as a compiler.</p> <p>Here&rsquo;s a story for this.</p> <p>Once I was using Docker to compile C++ modules to WebAssembly.</p> <p>This was an idea which came in my mind, when I wanted to do a PoC of a Wasm-based library for an existing implementation.</p> <p>The reasons why I choose this have been:</p> <p>The setup of the C++ -&gt; Wasm Toolchain wasn&rsquo;t really obvious. The way was too hard and too long for a PoC which should be done within few hours. So I checked the Docker images and luckily found one, which fitted in my case! (Side note: I don&rsquo;t know anymore which image this was.)</p> 48 hours of Rust https://tty4.dev/development/48-hours-rust/ Sun, 17 Jul 2022 03:00:00 -0100 https://tty4.dev/development/48-hours-rust/ <p>I wanted to have a look at the Rust programming language and gave me a small coding challenge.</p> <p>For sure, I could check the Rust documentation, read it from cover to cover, but this would not help me to <em>think</em> like a Rust developer. I think after the 48 hours coding challenge, I still don&rsquo;t think like a Rust developer and I need a lot more hours to be confident with the language. But I know a lot more about the way of problem solving, compile errors, types and language quirks than before and than I would when reading just the documentation.</p> Quick overview of how to setup Azure AD B2C (AADB2C) https://tty4.dev/development/setup-adb2c/ Mon, 11 Jul 2022 02:00:00 -0100 https://tty4.dev/development/setup-adb2c/ <p>Azure ADB2C (or: <em>AADB2C</em>) is a whitelabel authentication solution by Microsoft Azure.</p> <p>You can use AADB2C to implement a whole authentication flow within your Azure Cloud subscription with your own branding.</p> <p>This series describes the components of Azure ADB2C, which resources you need and how they do work together.</p> <h2 id="how-azure-adb2c-works">How Azure ADB2C works</h2> <p>AADB2C acts a central authority for your web/mobile applications or API.</p> <p>You can bind many identity providers like Facebook, Google, LinkedIN or E-Mail, Phone Call, SMS, &hellip; with ADB2C. All that without any implementation of an API!</p> On testing realtime services for the cloud https://tty4.dev/development/testing-realtime-services/ Fri, 08 Jul 2022 08:00:00 -0100 https://tty4.dev/development/testing-realtime-services/ <p>Testing realtime services for the cloud can increase the confidence for your service working correct.</p> <p>First, let us define what a realtime system is. Here&rsquo;s a good definition by <em>K. Erciyes</em> from <em>Distributed Real-Time Systems Theory and Practice</em> (ISBN: 978-3-030-22569-8)</p> <blockquote> <p>A real-time system operates with a time constraint, where the time that the output produced is significant [&hellip;] producing the output at some other time than the required time may be meaningless. Alternatively, a real-time system is a data processing system which responds to external inputs within a finite specified time called deadline.</p> Adding a NodeJS backend to Uberspace https://tty4.dev/development/uberspace-nodejs-backend/ Tue, 28 Jun 2022 04:10:00 -0100 https://tty4.dev/development/uberspace-nodejs-backend/ <p>Recently I added a NodeJS backend to my Uberspace webspace, which can be controlled by start/stop/logs scripts.</p> <p>This can be useful if you want to serve an API via your Uberspace account.</p> <p>Here is how I did it.</p> <p><strong>Note:</strong> For these examples <em>dennis</em> is the username of the uberspace. Just change it.</p> <h2 id="install-dependencies">Install dependencies</h2> <p>If you need to run for example a NestJS application instead of a pure node application, then install it globally. For NestJS it would be:</p> Kubernetes basics: DaemonSet https://tty4.dev/development/k8s-intro/1/ Wed, 22 Jun 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/1/ <h2 id="daemonset">DaemonSet</h2> <p>A DaemonSet ensures that all (or a specific part of) Nodes run a copy of a Pod.</p> <p>When a new Node is added, then a new Pod is added.</p> <p>DaemonSets are typically used to run a cluster storage, log collector or node monitor on every node.</p> <h2 id="specifying-a-daemonset">Specifying a DaemonSet</h2> <p>A DaemonSet specification consists of the <code>apiVersion</code>, <code>kind</code>, <code>metadata</code> and <code>spec</code> sections.</p> <p>The <code>spec</code> section is the indivudual one of the DaemonSet and consists the <a href="https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec"><code>DaemonSetSpec</code></a> object. The <code>spec.template</code> contains the pod information of the DaemonSet.</p> Kubernetes basics: ReplicaSet https://tty4.dev/development/k8s-intro/kubernetes-replicaset/ Tue, 21 Jun 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-replicaset/ <h2 id="replicaset">ReplicaSet</h2> <p>A ReplicaSet maintains a stable set of replica Pods and is used to ensure the availability of a specified number of Pods.</p> <p>A ReplicaSet contains a PodTemplate and creates/deletes Pods until the desired state is reached.</p> <p><em>But</em> mostly the direct usage of a ReplicaSet doesn&rsquo;t make sense. <code>Deployment</code> is also using a ReplicaSet to manage the availability of Pods <strong>and</strong> adds other useful features.</p> <p>So most of the time when a ReplicaSet is needed, a <code>Deployment</code> can be the better choice.</p> Kubernetes basics: Objects https://tty4.dev/development/k8s-intro/kubernetes-ingress/ Mon, 20 Jun 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-ingress/ <h1 id="ingress">Ingress</h1> <p>When you want to expose HTTP(S) routes from outside the cluster right to the services running within a cluster, then you need <code>Ingress</code>.</p> <p>If you configure an Ingress it can serve the following functionalities:</p> <ul> <li>externally-reachable URLs,</li> <li>loadbalancing traffic</li> <li>SSL / TLS</li> <li>name-based virtual hosting</li> </ul> <p>To fulfill the <code>Ingress</code> an <code>Ingress controller</code> is needed.</p> <h2 id="the-ingress-controller">The Ingress controller</h2> <p>&hellip; is needed to make the Ingress work! Just specifying it won&rsquo;t work.</p> Kubernetes basics: StatefulSet https://tty4.dev/development/k8s-intro/kubernetes-statefulset/ Sun, 19 Jun 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-statefulset/ <h2 id="statefulsets">StatefulSets</h2> <p><code>StatefulSets</code> are managing the deployment and scaling of a set of <code>Pod</code>s and add a sticky identity to each Pod. The Pods are not interchangeable - which are in <code>Deployment</code>s.</p> <p>StatefulSets are useful for persistent storage, unique network identifiers and for applications which require ordered updates, deployment and scaling.</p> <p>A StatefulSet can add set a PersistenVolumeClaim which returns to the provisioning of a storage which is available for the Pod.</p> Building a knowledge base as a software developer https://tty4.dev/no-category/building-knowledge-base/ Sat, 18 Jun 2022 10:00:00 -0100 https://tty4.dev/no-category/building-knowledge-base/ <p>When I started to work at my new job this year I also started to reflect the way I am taking notes and writing down things.</p> <p>In the companies I worked nearly every developer had Notepad++ installed and a lot of tabs where they wrote down cheatsheets, things they learned, log messages they try want to investigate and a lot more.</p> <p>But is this the correct way? Trying to find something which happened months earlier is not so good with unsaved Notepad++ tabs. I&rsquo;m more of an analog guy when it comes to notes: In nearly every meeting I am taking a lot of notes, scribbling and drawing diagrams of application architecture and designs in a sketchpad.</p> Kubernetes basics: Services https://tty4.dev/development/k8s-intro/kubernetes-services/ Sat, 18 Jun 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-services/ <p>If you want to expose an application (one or a set of Pods) as a network service, then the <code>Service</code> is the right choice.</p> <h2 id="why-we-need-services">Why we need services</h2> <p>Everytime a Pod is started - via a <code>Deployment</code> for example - it gets its own IP address. But when you do an update or change the specifications, this Pod gets deleted and another Pod gets started. But this one will get another IP.</p> Kubernetes basics: Deployments https://tty4.dev/development/k8s-intro/kubernetes-deployments/ Thu, 16 Jun 2022 00:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-deployments/ <p>A deployment describes the <em>desired state</em> and provides declarative updates for <em>Pods</em> and <em>ReplicaSets</em>.</p> <p>With a deployment you can rollout a <code>ReplicaSet</code>, update the state of a <code>Pod</code>, rollback deployments and <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#use-case">much more</a>.</p> <h2 id="deployment-specification">Deployment specification</h2> <p>A Deployment gets specified by a <code>YAML</code> file which is kind of <code>Deployment</code>.</p> <p>A Deployment needs at least the <code>apiVersion</code>, <code>kind</code> and <code>metdata</code> fields set.</p> <p>The <code>spec</code> field is the specification of the desired behavior of the deployment (<a href="https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec">DeploymentSpec</a>).</p> Get the tree of processes under Linux including the full command https://tty4.dev/development/tree-of-processes/ Wed, 08 Jun 2022 02:00:00 -0100 https://tty4.dev/development/tree-of-processes/ <p>If you want to get the tree of all processes which are running on your Linux machine, including the full command with parameters, you can use the following command:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ps -aef --forest | more </span></span></code></pre></div> The negative impact of communication between services in a distributed architecture https://tty4.dev/architecture/negative-impact-communication-distributed-architecture/ Fri, 03 Jun 2022 02:00:00 -0100 https://tty4.dev/architecture/negative-impact-communication-distributed-architecture/ <p>These days nearly every new project is set up as a microservice architecture. These small, fine-grained service can help with scalability, deployability, availability and testability, as they are focused on one small task. This modularity speeds up the time-to-market.</p> <p>But as in every architecture, you also need to keep some things in mind, to take the advantages of these architecture style. One is the communication between services. These can have a negative impact on the architecture characteristics.</p> How to fix H2 error: 'Syntax error in SQL statement ... expected identifier' https://tty4.dev/development/fix-h2-error-expected-identifeir/ Sun, 29 May 2022 02:00:00 -0100 https://tty4.dev/development/fix-h2-error-expected-identifeir/ <p>I had an Entity <code>User</code> in my Spring Boot application and storing information with a <code>Repository</code> to my MariaDB database worked fine.</p> <p>But when testing it with a H2 database, I got the following issue:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Syntax error in SQL statement &#34;select user0_.user_id as col_0_0_ from [*]user user0_ where user0_.email=? limit ?&#34;; expected &#34;identifier&#34;; SQL statement: </span></span><span style="display:flex;"><span>select user0_.user_id as col_0_0_ from user user0_ where user0_.email=? limit ? [42001-212] </span></span></code></pre></div><p>Well I know that H2 behaves sometimes different than MySQL even if you set the mode to MySQL. So I dig deeper.</p> Adding custom fonts to jsPDF in an Angular application https://tty4.dev/development/jspdf-add-font-to-angular-application/ Thu, 19 May 2022 02:00:00 -0100 https://tty4.dev/development/jspdf-add-font-to-angular-application/ <p>Recently I was adding new fonts to an Angular application which is using the awesome <a href="https://github.com/parallax/jsPDF">jsPDF</a> library. Here is how I did it.</p> <h2 id="tldr">TL;DR</h2> <ol> <li>Encode your .ttf file to bas64</li> <li>Add it to your application (replace the uppercase values with string):</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">doc</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">jsPDF</span>(); </span></span><span style="display:flex;"><span><span style="color:#a6e22e">doc</span>.<span style="color:#a6e22e">addFileToVFS</span>(<span style="color:#a6e22e">TTF_NAME</span>, <span style="color:#a6e22e">BASE64</span>); </span></span><span style="display:flex;"><span><span style="color:#a6e22e">doc</span>.<span style="color:#a6e22e">addFont</span>(<span style="color:#a6e22e">TTF_NAME</span>, <span style="color:#a6e22e">FONT_NAME</span>, <span style="color:#a6e22e">FONT_WEIGHT</span>); </span></span></code></pre></div><ol start="3"> <li>Do it again for all font weights. Where you set <code>FONT_WEIGHT</code> to one of <code>normal</code>, <code>italic</code>, <code>bold</code>, <code>bolditalic</code>.</li> </ol> <p>Done!</p> <p>Read on to see a more detailed description for your Angular application.</p> Hash tables, SSTables, BTrees: A quick glance at index types https://tty4.dev/development/database-indexes/ Mon, 16 May 2022 02:00:00 -0100 https://tty4.dev/development/database-indexes/ <p>If you think of a simple database, where you just append a file with new entries and query the whole file for an entry, you&rsquo;ll see a basic trade-off: Writing (= appending the file) is pretty simple and fast. Reading (= reading the whole file and querying every entry) can be complex and will take more time than writing.</p> <p>This is where indexes come into play. Let&rsquo;s have a quick glance at the most spread indices: <em>Hash indexes</em>, <em>SSTables</em> and <em>BTrees</em>.</p> Debug and analyze NodeJS Heap https://tty4.dev/development/nodejs-debug-heap-size/ Fri, 13 May 2022 02:00:00 -0100 https://tty4.dev/development/nodejs-debug-heap-size/ <p><img src="https://tty4.dev/nodejs/heapsnapshot.jpg" alt=""></p> <p>Sometimes you run into issues with memory leaks or <code>JavaScript heap out of memory</code> errors within your NodeJS application and need to analyze it.</p> <p>The Chrome DevTools ship with a useful tool for this where you can debug your application and inspect the Heap.</p> <p><strong>The following steps are needed to start inspecting your application:</strong></p> <ol> <li>Start Node process in <code>inspection</code> mode. For this add the <code>--inspect</code> flag in your run command:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>node --inspect index.js </span></span></code></pre></div><p>For <strong>Typescript</strong> based projects you can use:</p> Dynamic Disk provisioning with Kubernetes https://tty4.dev/development/dynamic-disk-provisioning/ Thu, 12 May 2022 02:00:00 -0100 https://tty4.dev/development/dynamic-disk-provisioning/ <p>Kubernetes can automatically provision <code>PersistentVolume</code> for you and make them available for your <code>PersistentVolume</code>s. This can be helpful if you are for example in a cloud provider like Azure.</p> <p>You need the interaction between the <code>StorageClass</code>, <code>PersistentVolumeClaim</code> and <code>Pod</code> resources to make it work.</p> <p><img src="https://tty4.dev/k8s/dynamicdisk/persistentvolumeclaim.drawio.png" alt=""></p> <h2 id="the-storageclass-resource">The StorageClass resource</h2> <p>For this you need to create a <a href="https://kubernetes.io/docs/concepts/storage/storage-classes/">StorageClass</a> resource which <em>describes the classes of storages you offer</em>.</p> <p>You can list your available <code>StorageClass</code> resources via the following command:</p> Kubernetes basics: Lifecycle hooks, Workloads and Resources https://tty4.dev/development/k8s-intro/kubernetes-workloads-resources-lifecycle-hooks/ Mon, 02 May 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-workloads-resources-lifecycle-hooks/ <p>Containers do have <a href="https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/">Lifecycle Hooks</a>:</p> <p><code>PostStart</code>: Is executed immediately after container is created. No guarantee is given that the hook will execute before containers ENTRYPOINT. Can be <code>exec</code> or <code>http</code>.</p> <p><code>PreStop</code>: hooks are not executed asynchronously from the signal to stop the Container; the hook must complete its execution before the TERM signal can be sent.</p> <p>If either a <code>PostStart</code> or <code>PreStop</code> hook fails, it kills the container.</p> <h2 id="workloads">Workloads</h2> <p>A <a href="https://kubernetes.io/docs/concepts/workloads/">Workload</a> is an application running on Kubernetes. It can be a single component or several components working together (running in a set of Pods).</p> How to find out how much space is left on Azure Disk resource https://tty4.dev/development/azure/azure-disk-space-left/ Fri, 29 Apr 2022 04:10:00 -0100 https://tty4.dev/development/azure/azure-disk-space-left/ <p>I was searching for a way to see the current free/available/used space of the <code>Disk</code> resource of Azure.</p> <p>Unfortunately in the Azure Portal you cannot see anything except of some I/O metrics. If you want more, you need to do some hacks with Monitoring tools.</p> <p>Too bad as I just needed the information.</p> <p>But well, if you have mounted the Disk for example via Kubernetes to a Pod. And you know at which directory, then you can just use the <code>df</code> command to fetch the information:</p> Kubernetes: Use kubectl to get information about PersistentVolume of a Pod https://tty4.dev/development/kubernetes-get-information-about-persistentvolume/ Thu, 28 Apr 2022 04:10:00 -0100 https://tty4.dev/development/kubernetes-get-information-about-persistentvolume/ <p>If you want to use <code>kubectl</code> to get information about a <code>PersistentVolume</code> of a <code>Pod</code>, then use the following steps:</p> <p>Get information about the Pod:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>kubectl describe pod [POD_NAME] -n [NAMESPACE] </span></span></code></pre></div><p>This will give you information about the Pod. Search for <code>PersistentVolumeClaim</code>. Or <code>grep</code> it with:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>kubectl describe pod [POD_NAME] -n [NAMESPACE]e | grep &#39;PersistentVolumeClaim&#39; -A 1 </span></span></code></pre></div><p>Use the <code>ClaimName</code> part to get information about the <code>PersistentVolumeClaim</code>:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>kubectl describe pvc [CLAIM_NAME] -n [NAMESPACE] </span></span></code></pre></div><p>Get the <code>Volume</code> out of the result of the above command and use it to describe the <code>Volume</code>:</p> Software architects as developers https://tty4.dev/architecture/software-architects-as-developer/ Wed, 27 Apr 2022 04:10:00 -0100 https://tty4.dev/architecture/software-architects-as-developer/ <p>In a classic way the software architect did some decisions on the <a href="https://tty4.dev/architecture/four-dimension-software-architecture">architecture characteristics</a>, the style and component structure.</p> <p>This created models have been handed over to the development team and told to <strong>design</strong> the system accordingly.</p> <p>But this has a pitfall: The communication is unidirectional from the architect to the dev team. This means:</p> <ul> <li>The architect will never get feedback from development team in regards of how and if they realized the decisions.</li> <li>The teams are split up and don&rsquo;t work together. In times of agile development this is not possible as software and requirements can change in every iteration.</li> </ul> <p>So a better way is to have a collaboration between the architect and software developer. Where the architect gets feedback by the dev team about the current status, pitfalls in the realization and in return the architect leads the team in a proper way to realize models and (domain) requirements.</p> Kubernetes basics: Pods https://tty4.dev/development/k8s-intro/kubernetes-pods/ Sat, 23 Apr 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-pods/ <p>The smallest deployable unit in a Kubernetes cluster is the <code>Pod</code>. And in terms of Docker it is <em>not</em> just a container. It is a <strong>group of one or more containers</strong> which share storage and network resources.</p> <blockquote> <p>A Pod is not a process. It is an environment for running container(s).</p> </blockquote> <p>So basically, a Pod can run multiple containers within a share context.</p> <p><em>But</em>: Usually Pods are not created individually like with the <code>YAML</code> file below:</p> Example for Dependency Inversion https://tty4.dev/development/dependency-inversion-example/ Fri, 15 Apr 2022 03:00:00 -0100 https://tty4.dev/development/dependency-inversion-example/ <p><strong><a href="https://tty4.dev/development/dependency-inversion">Click here to read more about the concepts of dependency inversion.</a></strong></p> <p>Let&rsquo;s assume that we have a button which shall (de)activate a lamp after a click.</p> <p>A **simple (non dependency inversion) approach could look like the following one:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Lamp</span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">boolean</span> isOn; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">turnOn</span>() { </span></span><span style="display:flex;"><span> isOn <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">turnOff</span>() { </span></span><span style="display:flex;"><span> isOn <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Button</span> { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> Lamp lamp; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">boolean</span> isPressed; </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">Button</span>(Lamp lamp) { </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">this</span>.<span style="color:#a6e22e">lamp</span> <span style="color:#f92672">=</span> lamp; </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">press</span>() { </span></span><span style="display:flex;"><span> isPressed <span style="color:#f92672">=</span> <span style="color:#f92672">!</span>isPressed; </span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span>(isPressed) { </span></span><span style="display:flex;"><span> lamp.<span style="color:#a6e22e">turnOn</span>(); </span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> { </span></span><span style="display:flex;"><span> lamp.<span style="color:#a6e22e">turnOff</span>(); </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span> } </span></span><span style="display:flex;"><span>} </span></span></code></pre></div><p>In this case the <code>Button</code> class has control over the <code>Lamp</code> class.</p> Concepts of Dependency Inversion https://tty4.dev/development/dependency-inversion/ Fri, 15 Apr 2022 02:00:00 -0100 https://tty4.dev/development/dependency-inversion/ <p><strong><a href="https://tty4.dev/development/dependency-inversion-example">Click here for a code example.</a></strong></p> <p>The dependency inversion principle was introduced first by Robert C. Martin in the year of 1996.</p> <p>It is a concept how to design applications to prevent rigidity, fragility and immobility.</p> <p>It can be used where one class sends a message to another.</p> <p>Citing M. Fowler the principle has two underlying concepts:</p> <ol> <li>High level modules should not depend upon low level modules. Both should depend upon abstractions.</li> <li>Abstractions should not depend upon details. Details should depend upon abstractions.</li> </ol> <p>In this series I&rsquo;ll show the concepts of dependency inversion and one example for it.</p> Debugging SIGTERM/SIGINT signals in a NodeJS application (VSCode) https://tty4.dev/development/debug-nodejs-sigterm-signals/ Thu, 14 Apr 2022 07:00:00 -0100 https://tty4.dev/development/debug-nodejs-sigterm-signals/ <p><em>tl;dr</em> Get the PID of the running process and send the signal via CLI.</p> <p>If you are working in a NodeJS environment, then you possibly do have something like the following code piece:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-typescript" data-lang="typescript"><span style="display:flex;"><span><span style="color:#a6e22e">process</span>.<span style="color:#a6e22e">on</span>(<span style="color:#e6db74">&#39;SIGINT&#39;</span>, <span style="color:#a6e22e">shutdownHandler</span>) </span></span><span style="display:flex;"><span><span style="color:#a6e22e">process</span>.<span style="color:#a6e22e">on</span>(<span style="color:#e6db74">&#39;SIGTERM&#39;</span>, <span style="color:#a6e22e">shutdownHandler</span>) </span></span></code></pre></div><p>This handles the <code>SIGINT</code> and <code>SIGTERM</code> signals received during the termination of a process.</p> <p>To stop your application gracefully, you can wait til all open connections to databases are closed or until all requests are done.</p> How to use class-validators with ValidationPipes in NestJS https://tty4.dev/development/nestjs-class-validators/ Wed, 13 Apr 2022 09:00:00 -0100 https://tty4.dev/development/nestjs-class-validators/ <p>If you want to validate the values of an incoming request body (like for example whether the e-mail is valid), then you can use in NestJS <a href="https://tty4.dev/development/validation-pipes-to-validate-params-nestjs">ValidationPipes</a>.</p> <p>This build-in feature allows you to abstract the validation away from your business logic. This makes it a good alternative to Joi.</p> <p>A package which has these built-in pipes and is a recommended way to use it in NestJS is the <code>class-validator</code> package.</p> <p>Here&rsquo;s how to use it.</p> Kubernetes basics: Objects https://tty4.dev/development/k8s-intro/kubernetes-basics-objects/ Tue, 12 Apr 2022 09:00:00 -0100 https://tty4.dev/development/k8s-intro/kubernetes-basics-objects/ <p>Kubernetes objects describe the desired state of the cluster.</p> <p>When an object is created, then Kubernetes will start it&rsquo;s work that the desired state is fulfilled.</p> <h2 id="kubectl">kubectl</h2> <p>Kubernetes objects get created either via the Kubernetes REST-API, where you describe via JSON the desired state. Or - and this is the way to go - via the CLI with <a href="https://kubectl.docs.kubernetes.io/references/kubectl/">kubectl</a>.</p> <p>In this case the command <code>kubectl apply</code> with the flag <code>-f</code> provides a <code>YAML</code> file with the specification.</p> Get the most out of Logstash https://tty4.dev/development/get-the-most-out-of-logstash/ Thu, 07 Apr 2022 09:00:00 -0100 https://tty4.dev/development/get-the-most-out-of-logstash/ <p>A good pipeline structure in Logstash gets you the most out of it!</p> <p>Here are three tips for best practices in Logstash and thinks I would have known when I started to work with it.</p> <h2 id="1-no-long-running-operations">1. No long-running operations</h2> <p>When you deploy Logstash you start it with either a default configuration or with your own settings.</p> <p>However you will probably be limited in workers and the batch size.</p> <p>This means that when you have some longer-running pipelines you will be limited in the size of the input as your Logstash instance gets stuck in job processing. Or in the worst case your instance will break!</p> The concepts of logstash pipelines https://tty4.dev/development/logstash-concepts/ Thu, 07 Apr 2022 08:00:00 -0100 https://tty4.dev/development/logstash-concepts/ <p>Either you want to work with data in your ELK-stack (Elasticsearch-Logstash-Kibana) or collect, parse and transform data from a variety of sources: <em>Logstash</em> is a good tool to choose.</p> <p>In this article I will describe some of the basic concepts of Logstash, which shall be the foundation for further work.</p> <h2 id="concepts-of-logstash">Concepts of Logstash</h2> <p>Logstash can be used to ingest data from one or more sources, transform it and send it to one dedicated output. Originally Logstash was used to collect logs from applications, but now it can be used for any input sources and data transformation by using a variety of plugins.</p> Looking forward to Kotlin and Wasm https://tty4.dev/development/looking-forward-to-kotlin-and-wasm/ Tue, 05 Apr 2022 08:00:00 -0100 https://tty4.dev/development/looking-forward-to-kotlin-and-wasm/ <p>Since 2018 I&rsquo;m looking after the progress of <a href="https://webassembly.org/">WebAssembly</a> as I think it is a quite interesting technology and can be the technology of the future.</p> <p>On the official Wasm page you can see which languages do <a href="https://webassembly.org/getting-started/developers-guide/">support the compilation to Wasm</a>.</p> <p>However one very interesting thing for me is the support of Kotlin.</p> <h2 id="the-current-state-of-kotlin-and-wasm">The current state of Kotlin and Wasm</h2> <p>With the introduction of the new <a href="https://blog.jetbrains.com/kotlin/2021/11/k2-compiler-kotlin-wasm-and-tooling-announcements-at-the-2021-kotlin-event/">K2 compiler</a> Kotlin also announced that there will be better and faster support for the compilation to Wasm.</p> Active/passive disaster recovery. Part 2: Design https://tty4.dev/development/disaster-recovery/disaster-recovery-design/ Wed, 30 Mar 2022 10:00:00 -0100 https://tty4.dev/development/disaster-recovery/disaster-recovery-design/ <p>This is the second of two posts in a series about disaster recovery.</p> <p>Part 1: <strong><a href="https://tty4.dev/development/disaster-recovery/disaster-recovery-concepts">Concepts</a></strong></p> <p>Part 2: <strong>Example design</strong> (this)</p> <p>Now that we have defined the words and described some theoretical concepts of disaster recovery, let&rsquo;s examine two different designs for an implementation.</p> <h2 id="requirements">Requirements</h2> <p>Let&rsquo;s imagine an application which has the following requirements:</p> <ul> <li>You have two endpoints to which you can send data: X and Y.</li> <li>Services A and B are running on different (geographical/virtual) places.</li> <li>Service A shall connect to X through cable C.</li> <li>Service B shall connect to Y through cable D.</li> </ul> <p>Which looks like a desperate try to flex with my alphabet knowledge is displayed in the following picture:</p> Active/passive disaster recovery. Part 1: Concepts https://tty4.dev/development/disaster-recovery/disaster-recovery-concepts/ Wed, 30 Mar 2022 09:00:00 -0100 https://tty4.dev/development/disaster-recovery/disaster-recovery-concepts/ <p>This is the first of two posts in a series about disaster recovery.</p> <p>Part 1: <strong>Concepts</strong> (this)</p> <p>Part 2: <strong><a href="https://tty4.dev/development/disaster-recovery/disaster-recovery-design">Example design</a></strong></p> <p>Time-sensitive applications often need to run nearly 100% of the time. Reasons are business requirements, or money and life critical applications.</p> <p>E.g. In the financial world an outage of 1 minute can mean the loss of a huge amount of data and money, so it is a high priority to prevent this applications from outages.</p> How and when to write good logs https://tty4.dev/development/writing-good-logs/ Tue, 29 Mar 2022 00:00:00 +0000 https://tty4.dev/development/writing-good-logs/ <p>The greatest navigators logged their activities on the sea so good, that years after the logbooks were found you could track day by day the route of their trip. One great example of that is the <em>USS Jeannette</em> which story has been written down by Hampton Side.</p> <p>When you are a developer, you should also take care of your logs. Even when you don&rsquo;t like the sea!</p> <p>In the last few years I have faced some situations where logs saved me from too much work or could have saved me some time on searching for root causes of failures.</p> Things to consider when building time-sensitive applications for realtime distribution https://tty4.dev/development/consider-things-time-sensitive-applications/ Fri, 25 Mar 2022 14:00:00 -0100 https://tty4.dev/development/consider-things-time-sensitive-applications/ <p>Distributing data in realtime has some exceptional challenges which you need to keep in mind when developing an application. In this article I want to have a look at an example I worked on and which things are needed to be considered during the development.</p> <h2 id="realtime-dissemination-index-value-data">Realtime dissemination: Index value data</h2> <p>The application is in the field of disseminating index value data in realtime to a vendor outside of the system.</p> The two topologies of event driven architectures https://tty4.dev/architecture/event-driven-architecture-topologies/ Mon, 21 Mar 2022 16:00:00 -0100 https://tty4.dev/architecture/event-driven-architecture-topologies/ <p>In a request-based model the system makes actions according to a request which comes usually by a user.</p> <p>An event-driven architecture reacts to a situation and makes actions regarding to this event.</p> <p>An example for an <em>event</em> is a price update at the stock exchange, which can trigger different <em>actions</em> like a buy, calculation, selling etc.</p> <p><img src="https://tty4.dev/event-driven/event-driven-request-based.drawio.png" alt=""></p> <h2 id="the-two-topologies">The two topologies</h2> <p>You can split the event-driven architecture in two topologies: The <em>mediator topology</em> and the <em>broker topology</em>.</p> Designing the realtime distribution component of an application https://tty4.dev/architecture/realtime-distribution/ Wed, 16 Mar 2022 15:40:00 -0100 https://tty4.dev/architecture/realtime-distribution/ <p>I worked once on a problem where the requirement was to consume one internal feed and send it to an server outside.</p> <p>We called the problem realtime distribution, because the data has been served by an internal websocket and changed every ~0.5 - 1 second for ~400 different sources.</p> <p>So an application which should distribute the data needed to subscribe up to 400 or even more socket channels and send the data out to the real world.</p> On responsiveness and performance in event-driven services https://tty4.dev/development/responsiveness-and-performance/ Mon, 14 Mar 2022 14:00:00 +0000 https://tty4.dev/development/responsiveness-and-performance/ <p>&hellip; or: why it is better to create jobs instead letting the user wait.</p> <p>One unique characteristic (or also a nice win) in event-driven architectures is that it gives us the capability for asynchronous communication.</p> <p>You can send an event and just don&rsquo;t care what happens with it (<em>fire-and-forget</em>) or send a request and <em>wait</em> for the reply. In the latter one event-driven architectures help a lot to increase the responsiveness of an application.</p> Implementing a STOMP client in a Spring Boot application https://tty4.dev/development/spring/spring-stomp-client/ Sun, 13 Mar 2022 19:00:00 -0100 https://tty4.dev/development/spring/spring-stomp-client/ <p>STOMP is a good and easy protocol to communicate in realtime via WebSockets.</p> <p>If you want to implement such a client in your Spring application, you can use <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/messaging/simp/stomp/package-summary.html">Springs simp package</a>, which provides all you need to start quickly.</p> <h2 id="requirements">Requirements</h2> <p>This article focuses on the STOMP client, so you need a server you can subscribe to and consume messages from. (See also: <a href="https://tty4.dev/development/stomp-server-producer/">A simple STOMP server &amp; producer application</a>)</p> <p>Also, you need the <code>spring-boot-starter-websocket</code> library as a dependency. E.g. in Gradle:</p> Output IntelliJ IDEA logs to a local file https://tty4.dev/development/intellij-logs-to-local-file/ Tue, 08 Mar 2022 16:00:00 -0100 https://tty4.dev/development/intellij-logs-to-local-file/ <p>If you want to store logs of a Gradle run to a file, just add the filepath (including the name) via the UI.</p> <p>For this you need to follow these options:</p> <p><code>RUN</code> -&gt; <code>Edit configurations</code> -&gt; <code>Application</code> -&gt; <code>Save console output to file...</code></p> <p>This file is overwritten on every rerun.</p> Message ordering with Java Semaphores https://tty4.dev/development/java-semaphores-for-message-ordering/ Sun, 06 Mar 2022 22:00:00 -0100 https://tty4.dev/development/java-semaphores-for-message-ordering/ <p>Semaphores are useful to limit the access of concurrent threads to a resource.</p> <p>This can be: A class instance, a variable or a method.</p> <p>You can use it to assert that in critical parts of your code no parallel requests are happening.</p> <h2 id="example-use-case-ordered-messages">Example use-case: Ordered messages</h2> <p>I used Semaphores in the financial world to assure, that time-sensitive messages had been send to an external resource in a specific order.</p> <p>Every message had an order number which was counted up on every send.</p> Helm hands-on: Overriding values https://tty4.dev/development/helm-hands-on-overriding-values/ Fri, 04 Mar 2022 17:30:00 -0100 https://tty4.dev/development/helm-hands-on-overriding-values/ <p>As soon as you got Helm up and running and understand the basics, you can start using it.</p> <p>Let&rsquo;s do a small hands-on example.</p> <h2 id="pre-requisites">Pre-requisites</h2> <ul> <li>A Kubernetes cluster</li> <li>Docker installed</li> <li>Helm installed</li> </ul> <h2 id="hello-world">Hello, World!</h2> <p>We&rsquo;ll use the <a href="https://artifacthub.io/packages/helm/cloudecho/hello">cloudecho</a> helm package.</p> <p>This is a small API running on Port 8080, which prints a <code>Hello, World!</code> on every request.</p> <p>To use it, we make use of the <code>helm repo add</code> command.</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>helm repo add cloudecho https://cloudecho.github.io/charts/ </span></span><span style="display:flex;"><span>helm repo update </span></span></code></pre></div><p>We can install it to our cluster with the following command:</p> Introduction to Helm https://tty4.dev/development/helm-intro/ Fri, 04 Mar 2022 17:00:00 -0100 https://tty4.dev/development/helm-intro/ <p>Managing YAML-files for Kubernetes can be sometimes really complicated: You have multiple files which describe for Kubernetes how to deploy the application. You have for example a Deployment, a Service, a ConfigMap and a Secret. All that files describe one desired state of your application.</p> <p>Managing all of these files and keeping an overview of all them can get a little bit hard.</p> <p>Furthermore you can&rsquo;t reuse these deployment files for another deployment without copying them and changing what you need for this other deployment.</p> Validate input parameters in NestJS applications with ValidationPipes https://tty4.dev/development/validation-pipes-to-validate-params-nestjs/ Thu, 03 Mar 2022 19:00:00 -0100 https://tty4.dev/development/validation-pipes-to-validate-params-nestjs/ <p><em>Used NestJS version: 8.4.0</em></p> <p>To validate user inputs like parameters or the request body in a REST call, you can use the built-in pipes of <code>NestJS</code>.</p> <p><code>NestJS</code> offers much more pipes in the <code>@nestjs/common</code> package. Head over to the <a href="https://docs.nestjs.com/pipes#built-in-pipes">documentation</a> if you want to check them out.</p> <h2 id="assure-that-the-parameter-is-an-integer">Assure that the parameter is an integer</h2> <p>If you want to assure that a given route parameter is an integer, you need to bind the <code>ParseIntPipe</code> to the <code>@Param</code> decorator as follows:</p> Spring @Scheduled annotation - fixedDelay vs. fixedRate https://tty4.dev/development/spring/spring-scheduled-fixeddelay-fixedrate/ Sun, 27 Feb 2022 08:00:00 -0100 https://tty4.dev/development/spring/spring-scheduled-fixeddelay-fixedrate/ <p>Once I had some fun to debug a scheduled method which executes a request every 1 second.</p> <p>I got told, that it works fine, but the request seems to get missed now and then.</p> <p>We have been using Spring Boots <code>@Scheduled(fixedDelay = 1000)</code> annotation:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>2022-01-24 11:13:47,974 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span><span style="display:flex;"><span>2022-01-24 11:13:48,976 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span><span style="display:flex;"><span>2022-01-24 11:13:49,991 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span><span style="display:flex;"><span>2022-01-24 11:13:51,013 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span><span style="display:flex;"><span>2022-01-24 11:13:52,016 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span><span style="display:flex;"><span>2022-01-24 11:13:53,024 INFO 160456 --- [ scheduling-1] c.m.n.controller.schedule.Scheduler : Method executed! </span></span></code></pre></div><p>You can see that the milliseconds counter rises. That is due the correct behavior of <code>fixedDelay</code>: It executes the method every second after the last execution got finished.</p> Introduction into the microkernel architecture style https://tty4.dev/architecture/microkernel-architecture-style/ Fri, 25 Feb 2022 06:00:00 -0100 https://tty4.dev/architecture/microkernel-architecture-style/ <p>Product-based applications which are monolithic and installed on the customer side can use the microkernel architecture to make customization possible.</p> <p>The microkernel architecture already exists for a long time and contains of <strong>two components</strong>:</p> <ul> <li>The core system</li> <li>Plug-in components</li> </ul> <p>The image below shows the topology:</p> <p><img src="https://tty4.dev/microkernel/microkernel.png" alt=""></p> <h2 id="core-system">Core System</h2> <p>The core system is the minimal functionality which is needed to run the system properly. In this case plug-in components can be added or removed to customize the system and extend the application however it is needed.</p> Typescript decorators with examples https://tty4.dev/development/typescript-decorators/ Thu, 24 Feb 2022 00:00:00 +0000 https://tty4.dev/development/typescript-decorators/ <p>Decorators in Typescript help us to add annotations and a meta-programming syntax for class declarations and member.</p> <p>You can add decorators to class declarations, method declarations, property declarations and parameters. Frameworks like NestJS and Angular are using decorators.</p> <p>Let&rsquo;s have a short look at decorators and how to use them.</p> <p>*<em>Currently decorators are an experimental feature. So if any of this code samples don&rsquo;t work, things may have changed.</em></p> <h2 id="project-setup">Project setup</h2> <p>If you want to try the following examples, start with initializing a new Typescript project in a directory:</p> The benefits and trade-offs of a Service-based architecture https://tty4.dev/architecture/service-based-architecture-benefits-and-tradeoffs/ Fri, 18 Feb 2022 00:00:00 +0000 https://tty4.dev/architecture/service-based-architecture-benefits-and-tradeoffs/ <p>Service based architectures have separately deployed services with an UI and one monolithic database.</p> <p>The latter one is probably the biggest difference to microservices. But that&rsquo;s not the only point where this style differs from microservices: You don&rsquo;t have some well-known problems like e.g. orchestration as you are allowed to implement coarse-grained services!</p> <p>The services in this style are also called <em>domain services</em>.</p> <p>If you take a look at the picture below, you&rsquo;ll probably think that you have already used this style in one of your applications.</p> Spring Boot and Kubernetes Configmaps https://tty4.dev/development/spring/spring-boot-kubernetes-configmap/ Thu, 17 Feb 2022 00:00:00 +0000 https://tty4.dev/development/spring/spring-boot-kubernetes-configmap/ <div class="alert-low"> <p>This document was last revised on 2022-09-24 and updated for the usage with <strong>Spring Boot 3</strong>.</p> <p>Check the <strong><a href="https://github.com/denniskawurek/spring-boot-3-configmap-demo">Repository</a></strong> for an executable example.</p> </div> <p>Deploying your Spring Boot applications in a Kubernetes environment will bring you many benefits like for example the usage of Configmaps.</p> <h2 id="what-are-configmaps">What are Configmaps</h2> <p>Configmaps are API objects which store data in key-value pairs. This data can be consumed by your application as environment variables or CLI arguments.</p> The four dimensions of software architecture https://tty4.dev/architecture/four-dimension-software-architecture/ Mon, 14 Feb 2022 00:00:00 +0000 https://tty4.dev/architecture/four-dimension-software-architecture/ <p>At the beginning phase of a new software architecture there are four dimensions of software architecture at which you should look and communicate with the stakeholders.</p> <h2 id="structure">Structure</h2> <p>This describes the type of architecture the system is implemented in. E.g. microservice, layered or microkernel.</p> <h2 id="architecture-characteristics--utilities">Architecture characteristics (&quot;-utilities&quot;).</h2> <p>These define the success <em>criteria</em> of a system.</p> <p>The architecture characteristics contain:</p> <ul> <li>Availability</li> <li>Reliability</li> <li>Testability</li> <li>Scalability</li> <li>Security</li> <li>Agility</li> <li>Fault Tolerance</li> <li>Elasticity</li> <li>Recoverability</li> <li>Performance</li> <li>Deployability</li> <li>Learnability</li> </ul> <h2 id="architecture-decisions">Architecture decisions</h2> <p>These define the <strong>rules</strong> about how the system should be created. For example an architect could decide to make the persistence layer of a layered structure only available by the service layer to make the underlying storage easy replaceable.</p> Introduction into the pipeline architecture style https://tty4.dev/architecture/pipeline-architecture-style/ Sun, 13 Feb 2022 00:00:00 +0000 https://tty4.dev/architecture/pipeline-architecture-style/ <p>The pipeline architecture appeared for the first time when developers started splitting the functionality into parts.</p> <p>If you&rsquo;re using the Unix terminal, you have probably written something like the following snippet:</p> <div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ cat error.log | grep <span style="color:#e6db74">&#39;error&#39;</span> </span></span></code></pre></div><p>That is exactly where the pipeline architecture plays a role!</p> <h2 id="pipes-and-filters">Pipes and filters</h2> <p>As you can see in the picture below, the pipeline architecture consists <em>pipes</em> and <em>filters</em>.</p> <p><img src="https://tty4.dev/pipeline/pipeline.png" alt=""></p> <p><strong>Pipes</strong> are the communication channel between filters and communicate unidirectional by accepting an input from one source and directing the output to another.</p> Implementing clients when you have a PDF which describes the server behavior https://tty4.dev/development/implementing-clients-from-server-view/ Fri, 04 Feb 2022 00:00:00 +0000 https://tty4.dev/development/implementing-clients-from-server-view/ <p>Technical documentation services like readthedocs.io help a lot to create documentations which are easy to read and understand for the users of an API.</p> <p>But in the enterprise world you&rsquo;ll not always get such an API documentation link which also has code snippets or examples you can use in your application.</p> <p>When consuming a third party service or sending data to it, you will sometimes get a PDF which describes how this services works and which messages it expects. No SDK or code snippets are provided.</p> Definition of and difference between modules and components https://tty4.dev/architecture/differences-modules-component/ Mon, 31 Jan 2022 00:00:00 +0000 https://tty4.dev/architecture/differences-modules-component/ <p>If you search for my title, you&rsquo;ll find a lot of discussions about the differences of modules and components.</p> <p>By reading literature about software architecture I also tried to get a definition of it. In my opinion it is really important to have a good overview what this terms mean to communicate ideas without any problems.</p> <p>So let me share with you what I found out about them.</p> <h2 id="modules">Modules</h2> <p>Modules are a set of parts or independent units. They can be used to create a more complex structure.</p> Do you know the protocols you're working with? https://tty4.dev/development/do-you-know-the-protocols-youre-working-with/ Sat, 29 Jan 2022 00:00:00 +0000 https://tty4.dev/development/do-you-know-the-protocols-youre-working-with/ <p>I never worked directly with the TCP protocol. As everyone with a CS degree I knew the 3-way handshake, it&rsquo;s place in the OSI-layers and had an idea of the segment structure.</p> <p>But then came the unexpected time where I needed to build up a service which communicates via TCP to another service and sends data to it.</p> <p>For a successful implementation I needed to develop an application which follows a protocol over TCP.</p> Review: Programming Typescript - Making your JavaScript applications scale (Boris Cherny) https://tty4.dev/development/typescript-cherny/ Sun, 23 Jan 2022 00:00:00 +0000 https://tty4.dev/development/typescript-cherny/ <p>Although I wanted to start with it, I didn&rsquo;t have the time to start reading technical literature until last years November. But then I wanted to refresh my Typescript skills and here we are.</p> <p>I didn&rsquo;t do much research to find some good books. As I know that the books from O&rsquo;Reilly have good visualizations and are easy to read and understand I favoured them.</p> <p>So the reviews led me to Boris Cherny&rsquo;s <em>Programming Typescript - Making your JavaScript applications scale</em>.</p> Debugging with Gradle: See what happens during gradle builds https://tty4.dev/development/gradle-debug/ Mon, 17 Jan 2022 19:09:00 -0100 https://tty4.dev/development/gradle-debug/ <p>Sometimes the normal <code>gradlew clean build</code> doesn&rsquo;t really help in the understanding why a gradle build fails.</p> <p>In my case this issue once occured when a build on a Jenkins server failed, but not on my local machine (<em>classic</em>).</p> <p>So there are two things which can be really helpful when debugging failed gradle builds.</p> <h1 id="being-very-verbose">Being very verbose</h1> <p>The following command will print you information during the gradle build, which can help you during debugging.</p> Experiences as a Mentor in a remote environment https://tty4.dev/no-category/experiences-as-mentor/ Sat, 15 Jan 2022 00:00:00 +0000 https://tty4.dev/no-category/experiences-as-mentor/ <p>In times of COVID-19 where a huge part of a team works mostly from home it may be a little bit hard to get into a new team and project.</p> <p>Knowledge may not be transferred fast enough or not communicated good.</p> <p>This in turn can lead to frustration for new team members and to higher costs for the company when a task which could be solved fast through good communication takes longer than needed. Also sometimes it could happen that something which already is implemented gets implemented twice, because who no communication happened.</p>