I've recently been doing some phone app development using Dart and Flutter. Although I've used languages with async/await before, the full consequences of that concurrency design had clearly never sunk in properly. It's much more subtle and complex than I'd realised: arguably the same as infinite threads on a single CPU core. Locking is most definitely still needed!
After a week off, I return to the distributed editor to write some tests for the server. How to test actors? How to write randomised and deterministic soak tests? And ultimately, how to build confidence that this system works like I claim it does.
I spent this week writing a new high-level binding in Go for LMDB.
I have chosen to use actors to structure the server. I believe this presents a simple model to understand, in terms of concurrency and state management, whilst allowing the server to scale and make use of multiple CPU cores. This week's instalment introduces the actors model, my actors library, and explains how I have used it for the distributed editor server.
Back to the fun stuff: how shall I store the document and its editing history on disk? How do I calculate what the document should look like after receiving an undo or redo message? How do I get the server to make reasonable use of its CPU and disk resources so that it can scale well? These are the questions I'm exploring this week.
Hugo started to annoy me, so I wrote my own static site generator.
This week I focus on the client: how does it send changes to the server; how does it process updates it receives from the server; how does it synchronise with the server when it first connects and then reconnects? It turns out that most of the problems the server faces, in terms of concurrent modifications to words, can also occur at the client because of concurrent changes received from the server, and received from the user typing.
In Part 1 I set the scene. Alice and Bob haven't fully specified the system, but they've certainly given me some requirements: The exact behaviour of concurrent edits is left for me to define, but I'm not allowed to solve it trivially (i.e. just do nothing), and the key requirement is that all users should end up seeing the exact same document fairly quickly, once they're connected to the server; They want the editing history to be stored so that undo/redo will work even if they disconnect and reconnect; They want to be able to edit the document locally even when disconnected from the network. Some sort of synchronisation will need to happen when they reconnect to the network.
The sun is bright and the sky's blue when I get to the office in London. As the lift doors ping open and I step out, a pair of heads near my desk swivel and look towards me. A sense of shame and embarrassment immediately forms in the pit of my stomach as I spot Alice and Bob sat waiting for me. I'd forgotten the meeting with them this morning that I'm late for.
Now I promise this isn't just a NixOS advocacy site; I do have some other content planned, honest! I just wanted to give a couple of examples of the using Nix as part of your daily workflow of building stuff.
Back in 2006, for reasons that made sense to me at the time, and make no sense to anyone at all now, I decided to buy some fonts and use them when writing my final-year thesis for university. I was writing my thesis in LaTeX. What followed was a week in which I read some pretty thorough documentation and slowly figured out how to convert fonts in normal TrueType and OpenType formats into the variety of formats that LaTeX needs, and how to install them.
I started using Linux as my main desktop OS in about the year 2000. I bought the Debian 2.1 "slink" CD-ROM set. At the time I also dabbled with other OSes too: Windows, BeOS, and also Minix. Over the last 20 years, through University and my career so far as a software engineer, Debian has been incredibly reliable, and has been my go-to choice whenever setting up a new machine. About five years ago I came across NixOS.