Missing Objects from Go Channels or: The coder is an idiot and used a queue like a slice…

This is probably self-evident to most sensible, educated people out there but… Golang Channels are queues and not slices!

An Idiot Writes…

So the following code looks superficially right – push the numbers 0 to 33 into a queue and then read them out with a loop, printing them to the screen as you go – except, when run, you’ll only get the numbers 0 to 16. Try it here and see.

package main

import (
	"fmt"
)

func main() {
	c := make(chan int, 100)
	for i := 0; i < 34; i++ {
		fmt.Println(i)
		c <- i
	}
	fmt.Println("===")
	fmt.Println("length")
	fmt.Println(len(c))
	fmt.Println("===")
	for i := 0; i < len(c); i++ {
		a := <-c
		fmt.Println(a)
	}
	fmt.Println("===")
}

So what’s the problem? Well, c – our Go Channel – doesn’t stay the same length after you interact with it. Why? a := <-c (the command to get the first object in the channel) alters the size of the channel as it removes the retrieved object – so a 34 object channel becomes a 33 object channel after we retrieve our first number meanwhile our counter, i, continues to count upwards until i is high enough that i < len(c) fails and the for-loop ends before the channel has properly drained.

Enlightenment…

The simple solution is to get the length of the channel once and to use that for your counter. Try it here.

package main

import (
	"fmt"
)

func main() {
	c := make(chan int, 100)
	for i := 0; i < 34; i++ {
		fmt.Println(i)
		c <- i
	}
	fmt.Println("===")
	fmt.Println("length")
	fmt.Println(len(c))
	fmt.Println("===")
	max := len(c)
	for i := 0; i < max; i++ {
		a := <-c
		fmt.Println(a)
	}
	fmt.Println("===")
}

More…

And why was I using a loop with a counter in it? Because I wanted to produce a numbered list of results and I was too lazy to read it out into a slice and then work with that. A better solution would probably involve replacing our channel reading loop definition as follows…

 for i := 0; len(c) > 0; i++

Counting Chrome Tabs on MacOS (Or, I have an open tabs problem!)

Another aide-mémoire; open Chrome tabs can, on MacOS, be counted via the following incantation. This particular incantation will pull the tab count from all open windows – minimised or otherwise – without the need to activate Chrome in any way.

osascript -e{'set text item delimiters to linefeed','tell app"google chrome"to url of tabs of windows as text'} | wc -l

Which, when run on my currently open set of tabs, comes back with a number slightly higher than 4,000.

Continue reading “Counting Chrome Tabs on MacOS (Or, I have an open tabs problem!)”

Period Sites in Period Browsers Machine Number 90 – Windows XP Home x86 with Amaya 6.0

It’s been a little while since I’ve posted about Period Sites in Period Browsers but, given I’ve just added my 90th combination of Operating System and Browser, it feels like a good time to flag it again.

Continue reading “Period Sites in Period Browsers Machine Number 90 – Windows XP Home x86 with Amaya 6.0”

cat /proc/cpuinfo for a Raspberry Pi 5 8GB Model B Rev 1.0

cat /proc/cpuinfo for a Raspberry Pi 5 8GB Model B Rev 1.0 running Raspberry Pi OS. It feels oddly sparse when compared to my NUC7PJYH NUC (Pentium Silver J5005) though I suppose that’s a RISC verses CISC thing…

cat /proc/cpuinfo 
processor	: 0
BogoMIPS	: 108.00
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x4
CPU part	: 0xd0b
CPU revision	: 1

processor	: 1
BogoMIPS	: 108.00
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x4
CPU part	: 0xd0b
CPU revision	: 1

processor	: 2
BogoMIPS	: 108.00
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x4
CPU part	: 0xd0b
CPU revision	: 1

processor	: 3
BogoMIPS	: 108.00
Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer	: 0x41
CPU architecture: 8
CPU variant	: 0x4
CPU part	: 0xd0b
CPU revision	: 1

Hardware	: BCM2835
Revision	: d04170
Serial		: XXXXXXXXXXXXXXXXXXXXXX
Model		: Raspberry Pi 5 Model B Rev 1.0

Next goal is to find time to try and get ESXi onto it…

Grabbing just the original files from Internet Archive objects

Time for another little magic spell that I need to jot down before I forget it. And this time for the Internet Archive’s command line tools.

Occasionally you’ll want to grab an object but you won’t want any of the Internet Archive-derived products. This can be done via…

ia download --source=original <object name>

And there you go – a whole bunch of bandwidth and disk saved!

Crashing Installers with Ubuntu Server for ARM.

Whilst playing about with the latest release of the ESXi for ARM Fling on a handy Raspberry Pi, I managed to waste a good few hours before I discovered that both the 22.04 and 23.10 releases of Ubuntu Server for ARM now require more than 1GB of memory to install without the installer crashing.

First we hang…
Continue reading “Crashing Installers with Ubuntu Server for ARM.”

Building QEMU 8.0 on Raspberry Pi OS

Introduction

Another passing year brings the 8th major release of the incredibly versatile emulation platform QEMU.

As always, the fastest, simplest way to get QEMU onto Raspberry Pi OS is via the default package manager. Unfortunately, version 5.2 – the version currently offered via the package manager – is almost 3 years out of date and an awful lot of development has occurred since.

Fortunately building QEMU 8.0 is not that difficult.

QEMU in the Raspberry Pi OS package manager…

…alas the offered version is incredibly out of date!

Continue reading “Building QEMU 8.0 on Raspberry Pi OS”