Configuring options in Go

Suppose, you have a function that takes an option struct and a message as input. Then it stylizes the message according to the option fields and prints it. What’s the most sensible API you can offer for users to configure your function? Observe: // app/src package src // Option struct type Style struct { Fg string // ANSI escape codes for foreground color Bg string // Background color } // Display the message according to Style func Display(s *Style, msg string) {} In the src package, the function Display takes a pointer to a Style instance and a msg string as parameters....

September 5, 2023

Dummy load balancer in a single Go script

I was curious to see if I could prototype a simple load balancer in a single Go script. Go’s standard library and goroutines make this trivial. Here’s what the script needs to do: Spin up two backend servers that’ll handle the incoming requests. Run a reverse proxy load balancer in the foreground. The load balancer will accept client connections and round-robin them to one of the backend servers; balancing the inbound load....

August 30, 2023

Limit goroutines with buffered channels

I was cobbling together a long-running Go script to send webhook messages to a system when some events occur. The initial script would continuously poll a Kafka topic for events and spawn new goroutines to make HTTP requests to the destination. This had two problems: It could create unlimited goroutines if many events arrived quickly It might overload the destination system by making many concurrent requests In Python, I’d use just asyncio....

August 23, 2023

Writing a TOTP client in Go

A TOTP1 based 2FA system has two parts. One is a client that generates the TOTP code. The other part is a server. The server verifies the code. If the client and the server-generated codes match, the server allows the inbound user to access the target system. The code usually expires after 30 seconds and then, you’ll have to regenerate it to be able to authenticate. As per RFC-62382, the server shares a base-32 encoded secret key with the client....

August 20, 2023

Interface guards in Go

I love Go’s implicit interfaces. While convenient, they can also introduce subtle bugs unless you’re careful. Types expected to conform to certain interfaces can fluidly add or remove methods. The compiler will only complain if an identifier anticipates an interface, but is passed a type that doesn’t implement that interface. This can be problematic if you need to export types that are required to implement specific interfaces as part of their API contract....

August 18, 2023

Go structured logging with slog

Before the release of version 1.21, you couldn’t set levels for your log messages in Go without either using third-party libraries or writing your own boilerplates. Coming from Python, I’ve always found this odd, considering that this capability has been in the Python standard library forever. However, it seems like the new log/slog subpackage in Go allows you to do that and a whole lot more. Apart from being able to add levels to log messages, slog also allows you to emit JSON-structured log messages and group them by certain attributes....

August 10, 2023