Skip to main content

9 posts tagged with "Design"

The shape of the framework — naming, layers, config and errors.

View All Tags

Prose that points instead of copying

· 9 min read
Kalin Krustev
Author of Blong

Every codebase has the same quiet failure mode. A paragraph of reasoning is written next to the code it explains — why a retry creates a new job instead of re-applying the failed one, why a cache keys on identity rather than on a version — and then the code moves. Six months later the paragraph is either wrong, or deleted by somebody who read it as noise.

The writing is rarely the problem. The storage is. The argument was copied into the one place that cannot maintain it, and a copy has no owner and no seat in any review.

Split the claim from the argument instead. The comment keeps the claim — the conclusion a reader needs at that point in the code — and points at where the argument lives: a decision record, a design note, an architecture decision record, an issue that is really kept. That is all a prose cross reference is. An address, not a copy.

// A retry creates a new job instead of deleting the failed one @@D-42

A cluster shaped like your code

· 6 min read
Kalin Krustev
Author of Blong

A Blong suite already knows what it is: which realms loaded, which layers registered, which orchestrator namespaces were claimed. So we stopped writing that down a second time and made the deployment read it.

cd suite/blong-suite && blong ./index.ts k8s

That writes the repository half of system/kustomize/ — Deployments, Services, volumes, RBAC — and exits; the declaration rides beside it as example/, because which suite a namespace runs is the tenant's decision rather than the repository's. Nothing was configured to say which layer belongs to which process, because the answer was already in the registry.

The other half belongs to the deployment. A second run over the same registry, given the values this cluster owns — the namespaces, the artifact's identity, the credentials the deployment declares — writes local/ beside the base, and kubectl apply -k system/kustomize/local composes the two. Only the base is committed: it is what a reader compares between two revisions, while the overlay is what changes between two deploys.

Intents: one word that picks the topology

· 5 min read
Kalin Krustev
Author of Blong

Most projects decide at build time what they are deploying. The web build gets the browser entry point, the service build gets the server one, the test build gets the mocks, and the differences between them live in environment files, build flags and a README about which command to run where. The topology becomes a property of the artefact, and the artefact has to be rebuilt to change it.

In Blong the topology is a word on the command line, and the code is the same code.

blong # dev + microservice + integration
blong integration blong-access.adapter # the access realm's adapter, as a test target
blong prod # the same realm, as a service
blong db # create and seed, then exit

Point Blong at a folder and run

· 5 min read
Kalin Krustev
Author of Blong

Most frameworks ask for a project before they will do anything: a manifest, an entry point, a directory layout the tool recognises. The generator that produces it is the first thing you learn and the first thing that goes stale, and it decides for you what a "project" is.

Blong's answer inverts that. A folder with a couple of handler files in it is a server — and if a suite names a realm whose folder does not exist, the folder is created from the template on the spot.

Change the config, keep the process

· 5 min read
Kalin Krustev
Author of Blong

Configuration is the one part of a running system that everybody edits and nobody enjoys restarting. A connection string, a timeout, a feature switch: the value is a line in a file, and the cost of changing it is a process that drops every connection it was holding. So the value stays wrong until the next deploy, and the deploy is scheduled for something else.

Blong treats the merged configuration as a live object: edit a watched file and the process re-reads it, diffs it against what it had, and swaps it in — without restarting, and without a request ever seeing half of the change.

A layer that describes itself

· 4 min read
Kalin Krustev
Author of Blong

Every framework starts with an entry point that wires things up, and that entry point is honest for about a year. Then an adapter grows a development URL, the orchestrator needs a namespace, a production deployment wants different credentials, and the file that was supposed to list components becomes the place where every component's configuration is written down — by someone who has to hold the whole component in their head to do it.

Blong moves that configuration into the component. A layer declares when it is active and what configuration it accepts, in its own file, next to the code it configures. The realm's entry point goes back to being a list of children.

Errors as a proxy

· 6 min read
Kalin Krustev
Author of Blong

Almost every framework says its errors are typed. What that usually means is that an error class exists somewhere, and every code path that raises it imports it, constructs it and hopes the message matches what the documentation promised. The definition and the call site drift apart, and the drift is invisible until a client reads a message that no longer describes the failure.

In Blong an error is data with a namespaced type, declared once in a realm's error layer, and reached from a handler through a proxy — no import, no constructor, no factory wiring, and a typo that fails before the function runs.

The name is the API

· 5 min read
Kalin Krustev
Author of Blong

Every framework has a naming convention. Almost none of them check whether you followed it, and none of them can tell you what a function does without reading its body. In Blong a handler's name is not documentation about the code — it is the API. The file the code lives in, the function it exports, the method the network carries, the URL that reaches it and the row that appears in the generated documentation are all the same string.

That single decision is why the framework can generate a routing table, a validation schema and an API document without being told anything twice — and why it can reject a name that disagrees with itself instead of quietly publishing it.

Every external system behind one adapter API

· 5 min read
Kalin Krustev
Author of Blong

Every external system arrives with its own habits. A Kubernetes watch stream never "returns", a Vault token expires, S3 wants a bucket and a key before it will talk, Kafka hands you a consumer group you did not ask for, and Redis speaks Lua when you want the answer to be atomic. Integration code is where those habits leak into a codebase — a client here, a credential there, an SDK call in the middle of a business rule.

Blong's answer is to make them all look the same. Kubernetes, Keycloak, S3, Vault, Slack, GitHub, SQL, MongoDB, Kafka and Redis reach the rest of the framework as one thing: a handler that answers a semantic triple.