Skip to content

Instantly share code, notes, and snippets.

@creachadair
creachadair / main_test.go
Last active May 19, 2022 16:01
Microbenchmark throughput latency of buffered channels
package main_test
import (
"fmt"
"testing"
)
func BenchmarkBuf(b *testing.B) {
for _, bs := range []int{0, 1, 2, 10, 32} {
b.Run(fmt.Sprint(bs), func(b *testing.B) {
@creachadair
creachadair / wake-on-change.md
Last active November 20, 2023 04:37
Waiting for a Value to Change in Go

Waiting for a Value to Change in Go

When multiple goroutines share access to a value that will periodically change, readers may wish to wait for a value to be updated before reading the value again. This can be solved using a condition variable:

var val *Thing
var mu = new(sync.Mutex)
var cond = sync.NewCond(mu)

func wait(old *Thing) *Thing {
@creachadair
creachadair / gh-run.sh
Last active May 10, 2022 15:40
A script to retry a failed GitHub actions run.
#!/bin/zsh
set -euo pipefail
readonly pollsec=5
if [[ "$#" = 0 ]] ; then
echo "Missing required run ID" 1>&2
exit 2
fi
@creachadair
creachadair / insert-text.md
Last active December 11, 2022 23:42
Inserting text at cursor on macOS

Insert Text at Cursor on macOS

Requirement: Enable Accessibility for the Terminal application.

tell application "System Events"
   keystroke "text to be inserted\n"
end tell
@creachadair
creachadair / award-checklist.md
Last active October 21, 2021 23:32
Hugo, Nebula and Clarke Winners Checklist

Hugo, Nebula and Clarke Winners Checklist

Extracted from the Google form posted in https://twitter.com/hammard_1987/status/1449453485343318025.

  • Children of Time (Adrian Tchaikovsky)
  • Rite of Passage (Alexei Panshin)
  • The Demolished Man (Alfred Bester)
  • The Calcutta Chromosome (Amitav Ghosh)
  • Ancillary Justice (Ann Leckie)
  • Dreams Before the Start of Time (Anne Charnock)
@creachadair
creachadair / waiter-sync.md
Last active October 26, 2021 04:24
Multiple waiter synchronization in Go

Multiple-Waiter Synchronization in Go

Often you have an object that is waiting for some result, e.g., an error to be delivered (once) by some goroutine. Multiple goroutines would like to wait for that to happen.

A traditional solution uses a condition variable, e.g.,

var result value
var ready bool
var mu sync.Mutex
@creachadair
creachadair / sync-channels.md
Last active November 24, 2024 23:59
Synchronizing close for multi-writer channels in Go

Synchronizing Close for Multi-Writer Channels in Go

(see also: https://godoc.org/github.com/creachadair/msync#Collector)

Many Go APIs allow multiple concurrent writers to a single channel, for example, to enqueue work for a task-processing API. When we do this, there is a tricky question of how to safely close the channel. Because this is tricky, many APIs do not bother, which complicates cleanup for the reader side of the channel. Dave Cheney has a good survey of channel corners that I recommend to anyone who knows Go well enough to be working in this space.

The basic problem is that writing to a closed channel triggers a panic. If some writer can detect that it is the "last", it can close the channel itself -- however that is often not practical unless all the writers are fully under the control of the API itself.

I have found a useful tactic for dealing with this situation.

@creachadair
creachadair / fast-mph.md
Created September 18, 2021 14:27
Fast minimal perfect hashing

Fast Minimal Perfect Hashing

Algorithm notes from

A. Limasset, G. Rizk, Rr. Chikhi, and P. Peterlongo: Fast and scalable minimal perfect hashing for massive key sets https://arxiv.org/pdf/1702.03154.pdf.

The goal of this algorithm is to create a conflict-free hash of the keys in the collection. The strategy is to create a zero-valued bit vector with at least 1 bit per key, and hash each key to a position in that vector. Any key that hashes uniquely is assigned that position, and removed from the working set.

@creachadair
creachadair / fuse-ref.md
Last active September 11, 2021 14:03
References on FUSE
@creachadair
creachadair / interfaces-and-tests.md
Last active October 8, 2021 22:23
Interfaces and satisfaction checks in Go packages

Interfaces and Satisfaction Checks in Go Packages

When a Go package defines a concrete type to implement some interface, it is common to ask the compiler to verify that your type satisfies the desired interface, e.g.,

package mything

import "some/other/pkg"

// Concrete implements pkg.Interface using a pellucid ammonite in