<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on random thoughts</title><link>https://riad.run/posts/</link><description>Recent content in Posts on random thoughts</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 28 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://riad.run/posts/feed.xml" rel="self" type="application/rss+xml"/><item><title>Migrating from GitLab CE to Forgejo</title><link>https://riad.run/posts/migrating-gitlab-to-forgejo/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><guid>https://riad.run/posts/migrating-gitlab-to-forgejo/</guid><description>&lt;p&gt;Recently we migrated our internal git server from GitLab CE to Forgejo. The experience has been great, IMHO.&lt;/p&gt;&#10;&lt;p&gt;We were running GitLab for a very long time. It served us well for so many years. Recently I updated it to the latest version. That&amp;rsquo;s when the problems began. It started failing randomly with lots of network errors. They updated the UI and probably introduced a lot of bloat, but the performance degradation was unmanageable — though to be fair, we were running that on a small server with only 3GB of RAM.&lt;/p&gt;</description></item><item><title>AI Coding Tools: My Experience and Practical Tips</title><link>https://riad.run/posts/ai-coding/</link><pubDate>Sat, 31 May 2025 00:00:00 +0000</pubDate><guid>https://riad.run/posts/ai-coding/</guid><description>&lt;p&gt;2024 and early 2025 were one hell of a wild ride. Lots of AI tools emerged from&#10;different companies. It&amp;rsquo;s not all that new, some were being developed for quite&#10;some time. And as a matter of fact, they are becoming more and more usable day by&#10;day. Recently, Anthropic released their latest model &lt;code&gt;claude-4-sonnet&lt;/code&gt;, which is&#10;great for coding as it writes fewer comments and can manage smaller tasks quite&#10;well. I&amp;rsquo;ve been using Cursor (aka the AI editor) for quite some time. There are&#10;also other alternatives. But as of writing this today, Cursor works best for me.&#10;I got my subscription because I kinda liked the tab model. If you&amp;rsquo;ve been exposed to&#10;any of the AI editors, you already know it can understand the pattern. If you&#10;change something in one line, it can understand and then can apply the&#10;same change for the next couple of lines, which is quite good and quite enjoyable&#10;too. No need to learn vim macro for that. Sorry vim users (myself included, I&#10;use vim mode all the time). Though in most cases with its tab model, it goes way&#10;beyond that simple change.&lt;/p&gt;</description></item><item><title>Understanding HTTP/1.1: Redirects in Go (Part 3)</title><link>https://riad.run/posts/http11-redirects/</link><pubDate>Sat, 25 Jan 2025 00:00:00 +0000</pubDate><guid>https://riad.run/posts/http11-redirects/</guid><description>&lt;p&gt;When I first learned about HTTP redirects I was confused about them. Which one do I need? One good way to always start from is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections" rel="external noopener"&gt;MDN Docs&lt;/a&gt; for any web standard related questions.&lt;/p&gt;&#10;&lt;p&gt;Read the docs and you don&amp;rsquo;t even need to read this at all. Bye. Or you can stay&amp;hellip;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;301&lt;/code&gt; is permanent redirect. So if you hit it once the browser will cache it and won&amp;rsquo;t bother to reach out to the server for subsequent requests. On the other hand &lt;code&gt;302&lt;/code&gt; won&amp;rsquo;t be cached and browser will hit our server every time user requests one of the urls. Same goes for &lt;code&gt;308&lt;/code&gt; and &lt;code&gt;307&lt;/code&gt;. But they&amp;rsquo;ll preserve the HTTP method. There&amp;rsquo;s a nice table for that in MDN Docs.&lt;/p&gt;</description></item><item><title>Understanding HTTP/1.1: Content-Type in Go (Part 2)</title><link>https://riad.run/posts/http11-content-type/</link><pubDate>Sat, 28 Dec 2024 00:00:00 +0000</pubDate><guid>https://riad.run/posts/http11-content-type/</guid><description>&lt;p&gt;Previously we&amp;rsquo;ve seen how to construct basic HTTP request and response with our simple TCP server. In this blog post we&amp;rsquo;ll go a bit deeper into the &lt;code&gt;Content-Type&lt;/code&gt; header and see Content-Type in action.&lt;/p&gt;&#10;&lt;p&gt;This is specifically HTTP thing. So when we&amp;rsquo;re sending data to an HTTP client we can specify what type of data we&amp;rsquo;re sending by using a header called &lt;code&gt;Content-Type&lt;/code&gt;. When the client is browser even if we don&amp;rsquo;t say the content type in header sometimes it&amp;rsquo;ll guess from the bytes sent to it. All these we&amp;rsquo;ll see in this blog post!&lt;/p&gt;</description></item><item><title>Understanding HTTP/1.1: TCP Server in Go (Part 1)</title><link>https://riad.run/posts/http11tcpserver/</link><pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate><guid>https://riad.run/posts/http11tcpserver/</guid><description>&lt;p&gt;The goal of this blog post is to spin up a TCP server and start sending requests to the server with various clients. That way we&amp;rsquo;ll see what type of data an HTTP client like &lt;code&gt;curl&lt;/code&gt; sends to the server. Out of all the versions of HTTP, we&amp;rsquo;ll focus on &lt;code&gt;HTTP 1.x&lt;/code&gt;. As it&amp;rsquo;s a text based protocol and we&amp;rsquo;ll be able to see what&amp;rsquo;s going on under the hood.&lt;/p&gt;</description></item><item><title>Structured Logging in Go with log/slog</title><link>https://riad.run/posts/using-slog/</link><pubDate>Thu, 14 Sep 2023 00:00:00 +0000</pubDate><guid>https://riad.run/posts/using-slog/</guid><description>&lt;p&gt;&lt;em&gt;So you want to use the new shiny structured logging library in golang&lt;/em&gt;&lt;/p&gt;&#10;&#10;&lt;h2 id="logslog"&gt;log/slog&lt;a class="heading-anchor" href="#logslog" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;slog&lt;/code&gt; (a &lt;em&gt;structured&lt;/em&gt; logging library in Go) has been included in the Go standard library starting from version 1.21. While Go already had a logging library, it was considered too simple for most use cases. For starters, it lacked the leveled logging feature. To achieve leveled logging, you had to create multiple loggers with the level as a prefix and direct them all to the same &lt;code&gt;io.Writer&lt;/code&gt;. This package, &lt;a href="https://github.com/spf13/jwalterweatherman" rel="external noopener"&gt;spf13/jwalterweatherman&lt;/a&gt;, accomplishes exactly that. There are also several third-party, excellent logging libraries available for structured logging, such as &lt;a href="https://github.com/rs/zerolog" rel="external noopener"&gt;rs/zerolog&lt;/a&gt;, &lt;a href="https://github.com/uber-go/zap" rel="external noopener"&gt;uber-go/zap&lt;/a&gt;, and &lt;a href="https://github.com/sirupsen/logrus" rel="external noopener"&gt;sirupsen/logrus&lt;/a&gt;, to name a few. Now that structured logging is included in the standard library, let&amp;rsquo;s give it a try.&lt;/p&gt;</description></item><item><title>Trace Logging in Golang</title><link>https://riad.run/posts/trace-in-golang/</link><pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate><guid>https://riad.run/posts/trace-in-golang/</guid><description>&lt;p&gt;&lt;em&gt;Disclaimer: This article is not about &lt;code&gt;runtime/trace&lt;/code&gt; package or trace profiling functionalities.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;Tracing is used to observe code execution paths. If you log something in a function and you see that output in the log file, then you know that the function has been executed. There is a log level defined in different logger implementations called &lt;code&gt;TRACE&lt;/code&gt;, which is the lowest log level in most loggers. The log won&amp;rsquo;t be present in the production environment, but when debugging, you&amp;rsquo;ll receive the traces. This is useful in situations where a debugger is not accessible.&lt;/p&gt;</description></item><item><title>Signal Handling and Graceful Shutdown in Go</title><link>https://riad.run/posts/go-signals-and-graceful-shutdown/</link><pubDate>Sat, 11 Mar 2023 00:00:00 +0000</pubDate><guid>https://riad.run/posts/go-signals-and-graceful-shutdown/</guid><description>&lt;p&gt;&lt;strong&gt;All the code samples used in this post are available&lt;/strong&gt; &lt;a href="https://github.com/riadafridishibly/go-graceful-shutdown" rel="external noopener"&gt;&lt;em&gt;here.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;&#10;&#10;&lt;h2 id="graceful-shutdown"&gt;Graceful Shutdown&lt;a class="heading-anchor" href="#graceful-shutdown" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h2&gt;&lt;p&gt;When a process is running for a long time, sometimes we want to quit the running program. If it&amp;rsquo;s a CLI process we press &lt;code&gt;CTRL+C&lt;/code&gt; or send specific kill signals. For GUI applications we quit from the menu or if the process becomes nonresponsive we find the &lt;code&gt;PID&lt;/code&gt; of the process and then run &lt;code&gt;kill -9 &amp;lt;PID&amp;gt;&lt;/code&gt;. These actions trigger an event and the event is sent to the specific process which sometimes causes the process to exit. In a stateful program, we want to save the states or perform cleanups before exiting the process. This safe exit process is called graceful shutdown.&lt;/p&gt;</description></item><item><title>Working with SSH in Linux and macOS</title><link>https://riad.run/posts/working-with-ssh/</link><pubDate>Thu, 22 Dec 2022 00:00:00 +0000</pubDate><guid>https://riad.run/posts/working-with-ssh/</guid><description>&lt;h2 id="table-of-contents"&gt;Table of contents&lt;a class="heading-anchor" href="#table-of-contents" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h2&gt;&lt;p&gt;&lt;em&gt;This post is not yet completed&lt;/em&gt;&lt;/p&gt;&#10;&#10;&lt;h2 id="tldr"&gt;TL;DR&lt;a class="heading-anchor" href="#tldr" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="generate-keys"&gt;Generate keys&lt;a class="heading-anchor" href="#generate-keys" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h3&gt;&lt;p&gt;Default RSA key,&lt;/p&gt;&#10;&lt;p&gt;This will generate an RSA key called &lt;code&gt;id_rsa&lt;/code&gt; in the &lt;code&gt;~/.ssh/&lt;/code&gt; directory.&lt;/p&gt;&#10;&#10;&lt;div class="code-block" data-lang="sh"&gt;&#10; &lt;div class="code-header"&gt;&lt;span class="code-lang"&gt;sh&lt;/span&gt;&#10; &lt;button class="copy-btn" type="button" aria-label="Copy code to clipboard"&gt;&lt;svg class="icon icon-copy" viewBox="0 0 24 24" width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;&lt;rect x="9" y="9" width="12" height="12" rx="2"/&gt;&lt;path d="M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1"/&gt;&lt;/svg&gt;&lt;svg class="icon icon-check" viewBox="0 0 24 24" width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"&gt;&lt;path d="M20 6 9 17l-5-5"/&gt;&lt;/svg&gt;&lt;span class="copy-label"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;I mostly prefer using the &lt;code&gt;ed25519&lt;/code&gt; key. To generate the key run the following,&lt;/p&gt;</description></item><item><title>Symmetric Encryption with ChaCha20-Poly1305 in Go</title><link>https://riad.run/posts/chacha20poly1305/</link><pubDate>Thu, 14 Jul 2022 00:00:00 +0000</pubDate><guid>https://riad.run/posts/chacha20poly1305/</guid><description>&lt;p&gt;&lt;em&gt;This post is not completed yet&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;Recently, I&amp;rsquo;ve started learning cryptography and in general different cryptographic concepts. So this blog post is a documentation of the process. I&amp;rsquo;ve linked a book where you&amp;rsquo;ll be able to find most of it in great detail.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;First, I want to recommend &lt;strong&gt;&lt;a href="https://cryptobook.nakov.com/" rel="external noopener"&gt;this book&lt;/a&gt;&lt;/strong&gt; to any software developer. If you haven&amp;rsquo;t read this book yet, I highly recommend reading it. It contains most of the commonly used cryptographic concepts which I believe enable any developer to write secure code in any domain.&lt;/p&gt;</description></item><item><title>String Hashing in C++</title><link>https://riad.run/posts/string-hashing-in-cpp/</link><pubDate>Mon, 22 Apr 2019 00:00:00 +0000</pubDate><guid>https://riad.run/posts/string-hashing-in-cpp/</guid><description>&lt;h2 id="what-is-hashing"&gt;What is Hashing?&lt;a class="heading-anchor" href="#what-is-hashing" aria-label="Link to this section"&gt;#&lt;/a&gt;&#10;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s think about a function &lt;code&gt;unsigned int hash(string)&lt;/code&gt;. This function will take a string as a parameter and return a unique ID let&amp;rsquo;s say an unsigned integer. This is called a hash function. It&amp;rsquo;ll generate a unique ID for every unique string. And same unique ID over and over for same string. Things get complicated when the two different strings generate same ID. This is called a hash collision.&lt;/p&gt;</description></item></channel></rss>