How Tailscale tracked down a 16-year-old SQLite bug →
We had repeated database corruption until we fixed a rare SQLite corruption bug. What does it take to find such an error?
Alex Chan’s personal website
We had repeated database corruption until we fixed a rare SQLite corruption bug. What does it take to find such an error?
To avoid awkward line breaks, I'm adding CSS to inline code snippets that contain hyphens or spaces.
I didn't know to check for UTF-8 byte order marks, so I made a mistake when converting text files. I was meant to use `encoding="utf-8-sig"`.
I'm not supposed to commit directly to main, but I often forget, so I have the computer remember for me.
When I save a photo, I write a sentence or two of descriptive context. It helps me remember what's in a photo, why I took it, and how I felt when I did.
I wrote a pair of regular expressions to find repeated words and phrases in my source code.
We traded the physical boundaries of dedicated rooms for the convenience of our always-on digital lives -- but recently I've been building those walls back up.
An API with an explicitly unused parameter is a testament to the web's commitment to backward compatibility.
When I saw a cool animation, I used the browser's native screen capture API to get a high-quality screen recording, audio included.
Who tests the tests? Test code isn't immune to bugs, so I'm using pytest's Pytester plugin to ensure my Playwright fixture is behaving correctly.
I thought rendering chat bubbles would be straightforward, but I found it tricky to get the CSS right and make the bubbles "shrink-wrap" to fit the text.
I'm using HTTP long polling and Python's threading module to tell my browser when my site has finished rebuilding. This gives me near-instant reloading, with no third-party dependencies.
I've written a Swift script that uses the FSEvents API to get notified of file changes, then I'm using stdout as a bridge to forward those notifications to Python.
Playwright is a testing library that lets you control a browser and check how the page is behaving, and it's great for testing and scripting web apps.
An SQLite table that caches expensive operations has dramatically sped up local development of this website.
For my local scripting, a lightweight wrapper around the Python standard library gets me a friendly API without the dependencies.
Python's virtual environments mean I can have many versions of the same package scattered across my machine. I've started keeping a list of my environments so I can see exactly what's installed, and where.
Recent developments have the cryptography world on alert, fearing a quantum computer capable of breaking public key cryptography is imminent. Unbeknownst to me, my blog is already protected.
Every year I use Python and a bit of CSS to create a fridge calendar that tells me about bin day.
When safety and normality are slipping away, how do we make our code, our communities, and our lives truly resilient?
I don't use libraries out of a sense of civic duty; I use them because they make me a happier, more adventurous, and more prolific reader.
Modern computers are more powerful than I know what to do with, but the norm is still to upgrade every few years. I want my current computer to last a decade, and I don't think that's unreasonable.
When it's dark, a large computer monitor is a fun way to make the room change into different colours.
I don't need GitHub or a cloud service to keep my Git repos in sync -- files and folders work just fine.
Cog is a tool for doing in-place text generation for static files. It's useful for generating repetitive config, like my web server redirects.