After learning about the existence of the Sonos Port from an episode of the Accidental Tech Podcast, I decided to give balenaSound a go on my Raspberry Pi 4.
I already ran raspotify on it so I could stream music to my aging hi-fi via the Pi’s 3.5mm headphone jack and some DIN connectors but the addition of AirPlay 2 and Bluetooth was tempting.
Looking at its source code, I could see balenaSound relies on shairport-sync to power its AirPlay features but I balked at the build instructions. Matt recommended balena for managing Raspberry Pi devices to me years ago but this seemed the ideal time to try it. Once you get past the confusing terminology (what exactly is a fleet anyway?), being able to see the status of services and see live logs in a web UI is impressive.
Sadly, I couldn’t get any of the features to work as it seemed to only ever output sound via HDMI despite setting various environment variables.
In the end, I re-imaged my Pi with the latest Raspberry Pi OS Lite with Raspberry Pi Imager and manually installed raspotify and shairport-sync. After setting the audio output with
raspi-config, everything works fine.
I would say this saved me the price of a Port but I impulse bought a Sub instead.
Two weeks after A—— was born, someone contributed a pull request against my gem, re2.
This week, after some back and forth, I was finally able to release the new functionality in re2 1.5.0.
The main change is the addition of an
RE2::SetAPI which binds to the underlying library’s class of the same name. However, this behaves differently between ABI versions of the library:
- Version 0 of
RE2::Set::Match()does not output any error information, instead returning
falseif a match fails for any reason.
- Later versions of re2 do output error information if requested.
The main blocker with the addition of this feature to my gem was how to handle this difference gracefully.
Things I considered:
- Could I backfill the behaviour of later re2 versions to version 0 so clients couldn’t tell the difference?
- No, version 0 doesn’t give me enough information to fully recreate the behaviour of later versions.
RE2::Set#matchbehave differently depending on your ABI version without warning, leaving the responsibility of knowing the expected behaviour to the user?
- I didn’t like the idea that upgrading the ABI version of the library would suddenly cause existing code to behave differently without warning.
- Should we expose a method that tells users which behaviour they will see?
- I added a
RE2::Set.match_raises_errors?method that will return true if the ABI version supports it as I need to rely on it in my tests.
- I added a
- Should we have two ways of calling
match: one that does not raise exceptions (available to all ABI versions) and one that does (available only to later versions)? If someone tries to call the latter API on an ABI version that doesn’t support it, raise an exception to explain it is unsupported.
The final API works like so:
# On ABI version 0 set = RE2::Set.new set.match("foobar") # RE2::Set::UnsupportedError: current version of RE2::Set::Match() does not # output error information, :exception option can only be set to false set.match("foobar", exception: false) # => false # On later ABI versions set = RE2::Set.new set.match("foobar") # RE2::Set::MatchError: #match must not be called before #compile set.match("foobar", exception: false) # => false
- Version 0 of
Last week, I said I am trying two things to prevent migraines. I lied as I’m also trying some other things:
- I’ve reduced the amount of coffee I drink in the morning (15g instead of 18g).
- I went for an eye test for the first time since January 2020 but my prescription hasn’t changed.
(So far, one or more of these things seem to be working.)
By Paul Mucur, on