<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Golang on Giedrius Statkevičius</title><link>https://giedrius.blog/categories/golang/</link><description>Recent content in Golang on Giedrius Statkevičius</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Wed, 05 Mar 2025 14:51:25 +0000</lastBuildDate><atom:link href="https://giedrius.blog/categories/golang/feed.xml" rel="self" type="application/rss+xml"/><item><title>Mirages of data ownership in Go</title><link>https://giedrius.blog/2025/03/05/mirages-of-data-ownership-in-go/</link><pubDate>Wed, 05 Mar 2025 14:51:25 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1015</guid><description>&lt;p&gt;Rust has a well-known borrow checker and a whole programming model that ensures there will be no data races. In particular, it is only possible to have one mutable reference or many read-only references but not both types at the same time. Technically, you might think that because Go is pass-by-value i.e. the arguments that you&amp;rsquo;re giving to a function are copied into some memory location before calling the function, it is impossible to have races in Go too. However, some types like slices and maps are implemented as references so you have to take a lot of care when returning them from a function because the caller might modify them.&lt;/p&gt;</description></item><item><title>My gRPC Annoyances</title><link>https://giedrius.blog/2024/06/07/my-grpc-annoyances/</link><pubDate>Fri, 07 Jun 2024 14:18:01 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1182</guid><description>&lt;p&gt;We have been using gRPC in &lt;a href="https://thanos.io"&gt;Thanos&lt;/a&gt; since Thanos inception - it has served us great and it has a ton of useful functionality, it solves a lot of problems, it is easy to use, and so on. However, I feel like some stuff is lacking, especially performance that will most likely never be fixed (or, I should say, changed). The framework just does not solve 100% of the things that the Thanos project needs right now. Let&amp;rsquo;s go through the list of my pet peeves.&lt;/p&gt;</description></item><item><title>Perils of /metrics data assertions</title><link>https://giedrius.blog/2024/02/28/perils-of-metrics-data-assertions/</link><pubDate>Wed, 28 Feb 2024 10:17:44 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1155</guid><description>&lt;p&gt;In the Thanos project the e2e tests are written in part using assertions on the metrics data. I have encountered a few challenges with those assertions that I wanted to share with you.&lt;/p&gt;
&lt;h2 id="always-check-for-the-maximum-possible-value"&gt;Always check for the maximum possible value&lt;/h2&gt;
&lt;p&gt;Writing tests on /metrics data means your testing harness continuously checks /metrics data to see whether some metric equals some value. If the metric takes some time to reach the maximum value, you might erroneously write an equals check that checks for a smaller value. Later on, this will lead to a flaky test situation.&lt;/p&gt;</description></item><item><title>Starting up GitHub sponsors and some recent postings work</title><link>https://giedrius.blog/2024/02/22/starting-up-github-sponsors-and-some-recent-postings-work/</link><pubDate>Thu, 22 Feb 2024 19:04:51 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1160</guid><description>&lt;p&gt;Hello everyone! I am happy to announce that I&amp;rsquo;ve set up GitHub sponsors on my &lt;a href="https://github.com/GiedriusS"&gt;profile&lt;/a&gt;. If you want to support my blog or my work on Thanos/Prometheus, and you have some free money then now you have a way to throw some money at these projects. Let&amp;rsquo;s see if I will even get one sponsor. I was thinking that maybe I should work on some custom features that could be behind a paywall. Let&amp;rsquo;s see when I will have some time to work on them.&lt;/p&gt;</description></item><item><title>Reproducing flaky Go tests using Linux cgroups and systemd</title><link>https://giedrius.blog/2023/07/17/reproducing-flaky-go-tests-using-systemd/</link><pubDate>Mon, 17 Jul 2023 20:07:40 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1139</guid><description>&lt;p&gt;Sometimes, the &lt;code&gt;-race&lt;/code&gt; option might not be enough to trigger/debug races in Go tests. You might have &lt;code&gt;time.Sleep()&lt;/code&gt; in a test thinking that some event will surely trigger in some time. You might run it on GitHub actions on a shared runner. Alas, you don&amp;rsquo;t see that event happen. What could have caused this? Most of the time it is because of the minimal CPU time allocated for your tests. The runners are shared between many projects and thus sometimes CPU might be very split between many processes.&lt;/p&gt;</description></item><item><title>Taxonomy of PromQL engines</title><link>https://giedrius.blog/2023/02/25/taxonomy-of-promql-engines/</link><pubDate>Sat, 25 Feb 2023 17:19:34 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=1021</guid><description>&lt;p&gt;PromQL kind of became a de facto standard of querying metrics. PromQL is the querying language of Prometheus. Over the recent years, a lot of different vendors started making products that are &amp;ldquo;compatible&amp;rdquo; with Prometheus. Julius Volz covers the general aspects of compatibility in his blog at &lt;a href="https://promlabs.com/promql-compliance-tests/"&gt;https://promlabs.com/promql-compliance-tests/&lt;/a&gt;. However, it would be interesting to look at the technical differences between PromQL engines embedded in each product. I will be mostly looking at the differences between engines in terms of how much they support concurrency, distributed evaluation features such as pushdown or general evaluation over many servers, optimizations, and how close they are to the vanilla engine.&lt;/p&gt;</description></item><item><title>Distributed Systems Magic: K-way Merge in Thanos</title><link>https://giedrius.blog/2022/09/08/distributed-systems-magic-k-way-merge-in-thanos/</link><pubDate>Thu, 08 Sep 2022 15:59:56 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=975</guid><description>&lt;p&gt;Oops, it has been such a long time since I wrote a post that I even accidentally forgot to renew my site! That&amp;rsquo;s bad. I definitely owe you a few new posts. Thus, here is another post in the distributed systems magic series.&lt;/p&gt;
&lt;p&gt;Recently I undertook the &lt;a href="https://github.com/thanos-io/thanos/pull/5296"&gt;task of improving the proxying logic in Thanos&lt;/a&gt;. If you are not familiar with it, the Query component of Thanos sends out requests via gRPC to leaf nodes to retrieve needed data when it gets some kind of PromQL query from users. This article will show you how it worked previously, how it works now, and the learnings from doing this.&lt;/p&gt;</description></item><item><title>Distributed Systems Magic: Groupcache in Thanos</title><link>https://giedrius.blog/2022/03/04/distributed-systems-magic-groupcache-in-thanos/</link><pubDate>Fri, 04 Mar 2022 10:19:50 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=953</guid><description>&lt;p&gt;This is a sequel to my previous blog post about trying to migrate to a newer version of protocol buffer API. In this blog post, I will tell you how we&amp;rsquo;ve managed to get &lt;a href="https://github.com/golang/groupcache"&gt;groupcache&lt;/a&gt; into Thanos during the previous LFX mentorship. The team consisted of &lt;a href="https://github.com/akanshat"&gt;Akansha Tiwari&lt;/a&gt;, &lt;a href="https://onprem.dev/"&gt;Prem Saraswat&lt;/a&gt;, and me. It would not have been possible to implement this without the whole team.&lt;/p&gt;
&lt;p&gt;In the beginning, let&amp;rsquo;s quickly go over what is groupcache and why it solves a few important problems in Thanos.&lt;/p&gt;</description></item><item><title>Things Learned From Trying to Migrate To Protobuf V2 API from gogoprotobuf (So Far)</title><link>https://giedrius.blog/2022/02/04/things-learned-from-trying-to-migrate-to-protobuf-v2-api-from-gogoprotobuf-so-far/</link><pubDate>Fri, 04 Feb 2022 16:03:25 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=928</guid><description>&lt;p&gt;During the most recent LFX mentorship program&amp;rsquo;s iteration, I had the honor to work on trying to migrate to &lt;a href="https://go.dev/blog/protobuf-apiv2"&gt;version 2 of the protobuf API&lt;/a&gt; from gogoprotobuf on the Thanos project with my one and only awesome mentee &lt;a href="https://twitter.com/im_rsawra"&gt;Rahul Sawra&lt;/a&gt; and another mentor Lucas Serven who is also a co-maintainer of &lt;a href="https://thanos.io"&gt;Thanos&lt;/a&gt;. I wanted to share my technical learnings from this project.&lt;/p&gt;
&lt;figure&gt;
&lt;img loading="lazy" src="https://giedrius.blog/wp-content/uploads/2022/02/image-1.png"/&gt;
&lt;/figure&gt;
&lt;p&gt;First of all, let&amp;rsquo;s quickly look at what protocol buffers are and what is the meaning of the different words in the jargon. Protocol buffers are a way of serializing data. It was &lt;a href="https://developers.google.com/protocol-buffers/"&gt;first made by Google&lt;/a&gt;. It is a quite popular library that is used by Thanos really everywhere. Thanos also uses &lt;a href="https://grpc.io/"&gt;gRPC&lt;/a&gt; to talk between different components. gRPC is a remote procedure call framework. With it, your (micro-)services can implement methods that could be called by others.&lt;/p&gt;</description></item><item><title>Surprising Behavior With inotify And ioutil</title><link>https://giedrius.blog/2021/03/06/surprising-behavior-with-inotify-and-ioutil/</link><pubDate>Sat, 06 Mar 2021 12:58:55 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=844</guid><description>&lt;p&gt;Recently I was working on trying to fix one flaky test of the &amp;ldquo;reloader&amp;rdquo; component in the &lt;a href="https://thanos.io"&gt;Thanos&lt;/a&gt; project. It was quite a long-standing one - almost took a whole year to fix this &lt;a href="https://github.com/thanos-io/thanos/issues/2622"&gt;issue&lt;/a&gt;. It is not surprising as it is quite tricky. But, before zooming into the details, let&amp;rsquo;s talk about what does this test does and what other systems come into play.&lt;/p&gt;
&lt;p&gt;Simply put, Thanos Sidecar works as a sidecar component for Prometheus that not just proxies the requests to it, captures the blocks produced by Prometheus &amp;amp; uploads them to remote object storage, but the Sidecar can also automatically reload your Prometheus instance if some kind of configuration files change. For that, it uses the &lt;code&gt;inotify&lt;/code&gt; mechanism on the Linux kernel. You can read more about inotify itself &lt;a href="https://man7.org/linux/man-pages/man7/inotify.7.html"&gt;here&lt;/a&gt;. Long story short, using it you can watch some files and get notifications when something changes e.g. new data gets written to the files.&lt;/p&gt;</description></item><item><title>Property-based testing in Golang</title><link>https://giedrius.blog/2019/07/08/property-based-testing-in-golang/</link><pubDate>Mon, 08 Jul 2019 19:35:23 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=529</guid><description>&lt;figure&gt;
&lt;img loading="lazy" src="https://cdn.pixabay.com/photo/2017/06/19/04/06/house-2418106%5F960%5F720.jpg"
alt="A simple house a.k.a. property"/&gt; &lt;figcaption&gt;
&lt;p&gt;A simple house a.k.a. property&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Testing software is ubiquitous and people naturally expect it to be a part of any kind of software development process. There are many different kinds of forms it can take:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;at the most rudimentary level: ad-hoc testing;&lt;/li&gt;
&lt;li&gt;integration testing;&lt;/li&gt;
&lt;li&gt;synthetic testing;&lt;/li&gt;
&lt;li&gt;and many others&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the forms that are quite novel is property-based testing. Essentially, the idea is to check if the software that you&amp;rsquo;ve produced espouses certain characteristics under inputs which have certain distinctive qualities. It sounds very similar to ordinary unit tests however here the catch is that a random number generator is leveraged in this case. Or, you can think of fuzzing but for ordinary code, not binary interfaces. It lets you run a bunch of tests very quickly and find the edge cases under which your code might not work as expected.&lt;/p&gt;</description></item><item><title>Introducing SAM: Similar Alerts Manager (My Side-Project)</title><link>https://giedrius.blog/2018/12/29/introducing-sam-similar-alerts-manager-my-side-project/</link><pubDate>Sat, 29 Dec 2018 10:50:22 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=350</guid><description>&lt;blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _______ _______ _______
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;( ____ \( ___ )( )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| ( \/| ( ) || () () | SIMILAR
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;| (_____ | (___) || || || |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(_____ )| ___ || |(_)| | ALERTS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) || ( ) || | | |
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/\____) || ) ( || ) ( | MANAGER
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;\_______)|/ \||/ \|
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;(sorry, I do not have a professional designer at my disposal)&lt;/p&gt;
&lt;h1 id="why"&gt;Why?&lt;/h1&gt;
&lt;p&gt;At the moment, Prometheus only supports a rudimentary way to look up what alerts have been firing in the past and there is no way to &amp;ldquo;persist&amp;rdquo; those metrics: there is a synthetic metric called &lt;code&gt;ALERTS&lt;/code&gt; which shows what alerts were firing in the past. That is not enough to be able to tell globally what alerts have been firing after Prometheus has restarted. You could use a full-fledged solution like Thanos to solve this problem however that is very cumbersome if you only want this small feature and&amp;hellip;&lt;/p&gt;</description></item><item><title>Capacity planning of Prometheus 2.4.2 + Thanos Sidecar 0.1.0</title><link>https://giedrius.blog/2018/12/16/capacity-planning-of-prometheus-2-4-2-thanos-sidecar-0-1-0/</link><pubDate>Sun, 16 Dec 2018 19:35:38 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=313</guid><description>&lt;figure&gt;
&lt;img loading="lazy" src="https://giedrius.blog/wp-content/uploads/2018/12/devops-what-is.png" width="955"/&gt;
&lt;/figure&gt;
&lt;h1 id="intro"&gt;Intro&lt;/h1&gt;
&lt;p&gt;Having a monitoring infrastructure is one of the tenets of the DevOps world. And, it seems that Prometheus and all of its extraneous integrations such as Thanos or Uber&amp;rsquo;s M3DB is taking over that world slowly. They give you a lot of improvements over the old Graphite set-ups such as increased reliability since Prometheus is based on HTTP which uses TCP thus you explicitly know when something goes wrong compared to UDP; it uses a pull based model so you explicitly know when something goes wrong and so on.&lt;/p&gt;</description></item><item><title>/etc/nsswitch.conf and /etc/hosts woes with the Alpine (and others) Docker image and Golang</title><link>https://giedrius.blog/2018/11/22/etc-nsswitch-conf-and-etc-hosts-woes-with-the-alpine-and-others-docker-image-and-golang/</link><pubDate>Thu, 22 Nov 2018 17:36:50 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=257</guid><description>&lt;p&gt;By default, the &lt;code&gt;alpine&lt;/code&gt; Docker image which is mostly used for Golang programs does &lt;a href="https://github.com/gliderlabs/docker-alpine/issues/367"&gt;&lt;em&gt;not&lt;/em&gt;&lt;/a&gt; contain &lt;code&gt;/etc/nsswitch.conf&lt;/code&gt;. Golang&amp;rsquo;s &lt;code&gt;net&lt;/code&gt; package used to do a sane thing when that file did not exist back in the day (before April 30, 2015) i.e. they checked the &lt;code&gt;/etc/hosts&lt;/code&gt; file first, and then moved on to trying to query the DNS servers.&lt;/p&gt;
&lt;p&gt;However, it was changed later - now Go&amp;rsquo;s resolver tries to query the local machine as per the manual page of &lt;a href="http://man7.org/linux/man-pages/man5/nsswitch.conf.5.html"&gt;&lt;em&gt;nsswitch.conf(5)&lt;/em&gt;&lt;/a&gt;. You can find the commit &lt;a href="https://go-review.googlesource.com/c/go/+/9380/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Go's http.Transport and 408 response code - what's the relationship?</title><link>https://giedrius.blog/2018/10/25/gos-http-transport-and-408-response-code-whats-the-relationship/</link><pubDate>Thu, 25 Oct 2018 19:31:18 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=289</guid><description>&lt;h1 id="intro"&gt;Intro&lt;/h1&gt;
&lt;p&gt;Golang&amp;rsquo;s standard library&amp;rsquo;s &lt;code&gt;http&lt;/code&gt; package provides a type &lt;code&gt;http.Transport&lt;/code&gt; which implements some low-level methods for transporting HTTP requests hence the name. It is very useful - usually other libraries want variables of types which implement that interface - however, you might have noticed that using it in combination with haproxy and HTTP keep-alive connections sometimes make these kinds of messages appear in your program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2018/08/21 11:22:33 Unsolicited response received on idle HTTP channel starting with &amp;#34;HTTP/1.0 408 Request Time-out\r\nCache-Control: no-cache\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;408 Request Time-out&amp;lt;/h1&amp;gt;\nYour browser didn&amp;#39;t send a complete request in time.\n&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;\n&amp;#34;; err=&amp;lt;nil&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And in your haproxy logs:&lt;/p&gt;</description></item></channel></rss>