I've added a ui to ping (status monitor) and added heart checks to the other sites and that's all working nice.

I still need to add rules that mean I only get one text per outage, rather than one per failed ping. I'm also thinking about adaptable rules for sites ("ping every n minutes, at least m consecutive fails").

On the other hand, a simple, offsite, cheap status checker: Yup.


What we have here is a state machine. A given endpoint is either FINE, FAILING (n), FAILED, or RECOVERING(n). Failing and recovering states have n copies.

Possible transitions:

FINE & !ping(ok) => Failing(0)

Failing(x) & ping(ok) => Fine Failing(x < n) & !ping(ok) => Failing(x+1) Failing(x == n) => Failed

Failed & ping(ok) => Recovering(0)

Recovering(x < n) & ping(ok) => recovering(x + 1) Recovering(x) & !ping(ok) => Failed Recoverin (x = n) => Fine

Or, in English, if we're fine and we get a bad ping, to into failing. Any good pings in failing take us back into fine. Otherwise, each bad ping takes us one step closer to failed. After n bad pings in a row we move into failed (and this transition sends a message). In failed, the situation is reversed. A good ping in failed puts us in recovering, any bad pings in recovering put us back into failed (no notification). After n good pings in a row we move back into fine (and probably trigger a notification).

Each endpoint needs to track it's current state, and the length and sign (good/bad) of the current streak. (Streaks have a minimum length of 1 since they're driven by the ping that has just returned)

StateNames enum (Fine, Failing, Failed, Recovering) PingResult enum (Ok, NotOk) Streak struct {uint count, PingResult sign}


Idle question: What are good uses for a sms to http endpoint? (That is, what useful text messages could I send my machine?)


I've been thinking about a calculator/scratch pad for a while, and I've just realised that what I actually want is the Smalltalk environment.

Imagine a blank screen. Click anywhere and start typing. Select text, right click and 'evaluate'. Right click to bring up tools (number pad, calendar, file upload whynot, timers, API calls). I also want to be able to link bits together, so the output of one calculation can feed into another.

It's persistant (changes are saved straight away) and maybe networked (so that I can open the page here or on my phone or at work).

Its got bits of OneNote, but that doesn't have any calculation/scripting.

I'm also thinking about 'layers' rather than 'pages' - layers stack on top of each other, and can be turned off and on. Disabled layers don't contribute to calculations.

Adding in data pipelines, to take e.g. a JSON source, parse it, filter it, reduce it, give an output, or a base64 encoded blob, decode it to utf8.


Chunks have got properties:

  • version
  • position (top, left)
  • dimension (width, height)
  • content
  • title?
  • tags[]
  • id (auto-generated)
  • input[]
  • output[]

And methods:

  • update()

Chunk service commands/events:

  • create(top, left)/created
  • move(top, left)/moved
  • resize(width, height)/resized
  • delete()/deleted
  • setContent(content)/contentChanged

Just noticed that my status app is ipv6 only.

And ok, I kind of noticed when I only have it an ipv6 address, but it didn't really sink in until just now.

(I was about to be all "welcome to the future babe!", but then I checked with 4g and it turns out my mobile connection isn't ipv6? I could have sworn...)


"My lady, you are both beautiful and wise, a rare and treasured combination in these troubled times. Would ye fancy a quick knee trembler in the trees yonder?" She snorted a laugh, and quickly regained control. "Alas," she said, and gestured to the collar around her neck. "My lord has required me to wait upon his immediate return, else how could I refuse such an eloquent and specific proposal."


Feeling ok today, getting stuff done at work (bits of dropping into other peoples problems and solving them, sling work doing the work I should be doing).

Bought myself a new Bluetooth mouse so I can play games on my laptop without borrowing Husband's spare wired mouse.

Moved the cables from their boxes in the box room to the new shelves in the study. (I'm going to call them shelves, even though it's not quite right, but "The IKEA Kallax storage unit" takes a while to type). I've also bought a bunch of reusable (velcro) cable ties that I'll start using sooner or later to actually tidy the cables.

So just basic life stuff, yeah?


So that's a (mostly) functional core built for the notes thing. It takes in commands and the current state of notes and generates events based on the command.

The ui listens for browser events, turns them into commands, and sends the commands to the core while waiting for the core to generate events for the ui to react to.

I'm starting work on a storage service that will listen for events and write them (or rather, the materialized states) to disk. It will also listen for events like to DOMContentLoaded, and use that as a trigger to dispatch it's own (noteLoaded) events via the core.

(I've just realised, when the UI makes a change, it can listen for a noteSaved event to let the user know their change is safe).

'Disk' in the case will be browser local storage, I'm also planning a network service that will ship events to (and from) other machines (for things like offsite backup and shared context).

Should be fun.


I've started getting serious about type checking in JavaScript by using typescript/jsdoc notation to label functions and variables, and it's turning out to be really nice/useful/verbose.

I could go full on typescript, except the compiler is a node.js script, and I've still got serious reservations about that whole ecosystem.


Starting to put together the server side of notes, and it looks like I'm going to use "workspaces" as the holder for notes.

All notes must be in a workspace.

The index page shows a list of known workspaces (stored in a table in the database) and create/delete buttons.

A "My first workspace" is created if the list of workspaces is empty. It's should be created from a template (but with unique ids for notes).

User can bookmark a workspace, and/or set one as default.

Workspaces have 'create workspace ' buttons.

Nothing is saved to the server until the user opts in.

Workspace commands:

  • Create(name) => workspace-created(name, id)
  • Load(id) => workspace-loaded(name, note[])
  • CreateNote(id, note) => note-created(id, note)
  • UpdateNote(id, note) => note-updated(id, note)
  • DeleteNote(id, note) => note-deleted(id, note)
  • Delete(id) => workspace-deleted(name, id)

Putting together a language (lox, again) needs a tokenizer (basic), a parser (got two examples), and a backend (again, two examples).

I prefer the Pratt parser (over the recursive decent), it looks much easier to extend. I also liked having an ast over jumping straight into code generation (with the bytecode vm).

I'd like to make a self hosting compiler, just to get that box ticked off. If I target wasm (or JavaScript, I guess), then I can run in the browser, although I'd really like something that can run on either browser or server.

I've gone though bits of this process a bunch of times now, and I'm not seriously thinking about picking up one of those old versions. I've got a version somewhere that's got arrays and a few other things, but that's written in C.

I think I want to do this version in C#, with the Pratt parser and the AST. I should be able to then write visitors to generate a few different backends - JavaScript, wasm, C# expressions, and maybe CLR bytecode (in rough order of difficultly).

I also want to write it as a library first. I need to make a choice about where to put generated nugget packages (and it's going to be GitLab) so I can start putting a library of useful stuff together.


After lox, the next library is 'web' for a bunch of asp.core stuff:

  • Openid Auth setup (not big, but irritating)
  • JavaScript, at least the lib.js that turns up places
  • Maybe a _Layout.cshtml and supporting files (like rocket.svg, basic site.css with a header/content/footer grid).

There are a few themes here. First, make it easier to start a project (so let's add a new project template to the list). Next, take out some of the style decisions. Finally, centralise some common code so that improvements can be distributed.


I don't want the template to embed files directly where possible, instead of should depend on the appropriate libraries.


Immune system is running hot today (has been last 3? days). Sore throat, too much phlegm at the back of my mouth, coughs and sneezes today, and mild cognitive deficit (today).

I'm calling it a cold. First one in ages, mildly sucks, but then it's a mild cold.


Still sick. Flippin' body lied to me this morning, said I was fine, but then gave up after about an hour.

However, I've dug out my old bluetooth keyboard and hooked it into the phone, so might be able to get some stuff done anyway..




  • poll says theres new data available on our socket
  • add data to the buffer
  • Check for EOL in the new data
  • If found, check state and hand off to the next routine

Connections have a current request (and probably current response). Requests have:

  • Method (enum, why not)
  • Target URI/path
  • Header hash (think about multiple headers)
  • Possible content (in memory vs cache to disk)

[This stack overflow answer] (https://stackoverflow.com/a/17905131/195833) shows how to do state machine functions (functions that return pointers to functions of their type)


For this http server, main loop looks something like:


// set up listen socket
int listenSocket = ...

// Install signal handler(s) to clear the running flag

struct pollfd *pollData = ... // add listenSocket to poll 

while (running) {
  int pollResult = poll(...)

  switch (pollResult) {
    case -1:
       // Handle poll error, probably by falling out the loop
    case 0:
      // Poll timeout, continue the loop
      // (going this to give signals a chance to gracefully shut down)
      continue;
  }
  
  // this is where i got bored/ran out of energy
}

// Tidy up

// close listen socket
// close client sockets




To remember your current position in the blog, this page must store some data in this browser.

Are you OK with that?