Skip to content

Document Fabric load balancing, status-check, and taking an unhealthy node out of rotation - #729

Merged
dawsontoth merged 1 commit into
learn/administration-production-reliabilityfrom
docs/fabric-node-availability
Oct 14, 2026
Merged

dawsontoth merged 1 commit into
learn/administration-production-reliabilityfrom
docs/fabric-node-availability

Conversation

@dawsontoth

@dawsontoth dawsontoth commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

A hedgehog dims the lantern on a cracked bridge while woodland travelers cross the two lit bridges

⊙ Problem

Fabric's load balancer sends new connections to every node whose GET /status answers 200. That answer comes from the status-check component Fabric deploys, which reads the node's availability record. So a node keeps getting traffic while its application fails, and no page covers the component or a safe way out.

❓ Your call: is a guide with a sample loop warranted?

Yes: the pattern already runs in production on Fabric, and without its rules a loop can fight Fabric or take every node out. The alternatives are documenting only the manual drain, or shipping the loop as a published component so copies get fixes; both are easy to move to later.

💡 Solution

❓ Your call: fix #671's Administration page there or here?

#671's traffic-admission guide says nothing in Harper acts on set_status, and has Fabric readers deploy the npm @harperdb/status-check, which collides with Fabric's /status. This PR only reconciles from the Fabric side. I'd scope those lines to self-managed clusters in #671; editing them in this stacked PR is the alternative.

❓ Your call: are the Fabric facts right?

The pages say only what I could verify in source or on a live Harper, or was told. A Fabric owner should confirm these before the PR leaves draft.

Questions for a Fabric owner
  1. The load balancer's check: interval, timeout, how many failures take a node out, and whether anything but 200 passes. The guide's 30 s and 60 s don't allow for it.
  2. Is the balanced name DNS-based? Then cached answers keep clients on a node that went out until the TTL ends; the caveat names only open connections.
  3. Where customers find each node's own hostname, and whether its Operations API answers on :9925, where the CLI sends a target with no port.
  4. Does Fabric set Available on new nodes, and after an upgrade even when the node was Unavailable before it?
  5. Does status-check show in Studio's Applications list, where a customer could remove it?
  6. Should server.workerIndex, which the guide uses, get an entry in reference/http/api.md?
  7. The public status-check-fabric README says table writers may POST and DELETE; only super users can (a non-super user gets 403). Fix it upstream?
  8. Two harper CLI faults on 5.3.2, worked around here: harper restart printed "Harper is already running" and restarted nothing, and harper get_status id=availability on a node with no record errors after printing null.

🔧 Changes

✅ Verification

  • Checked against harper source at v5.3.2: the record's table is persisted with replicate: false, set_status stores only { status }, server.operation() skips authorization by default, and the set_status role grant first shipped in v5.3.0.
  • Ran the guide's code, copied from the formatted page, on a throwaway Harper 5.3.2 beside the real status-check, including the harper login flow and a role limited to set_status. Every drill step behaved as the guide says (details below).
  • npm run format:check is clean. npm run build fails only on Add production reliability guides for Harper operators #671's own TODO link; with that link patched locally, it passes and every new link resolves.
Live results on Harper 5.3.2
  • /status: 404 with no record, 200 with Available. DELETE: 401 anonymous, 403 non-super user, 204 super user. The record survived a full stop and start.
  • A role whose operations list is set_status and get_status ran set_status; list_users and drop_user were refused, and its POST /status got 403.
  • The loop ran on one worker of two. It went out 30-35 s after the dependency failed, and came back 60-66 s after it recovered.
  • With the other node's /status at 404, it stayed in and warned once; it went out at the next look once that node returned.
  • An operator's Available while out was left alone, including across a stop and start (46 s, still failing). An operator's Unavailable was never undone.
  • When the other node went out with it, it came back 1.5 s later, logged that it would stay in until a restart, and did.
  • A pending marker claimed an Unavailable written 0.5 s after it, and left alone one written 10 s after it.
  • 200 concurrent /Health requests reached the dependency once.

🤖 Generated by Claude Opus 5.5 via Claude Code; posted via @dawsontoth.

Related PRs: #671 overlaps (this PR is stacked on it; same set_status paragraph), 10 others independent
Complexity: medium

Review-Coverage: authored=claude; ran=cursor-composer,codex,gemini,cursor-muse; adjudicated=domain; declined=cursor-grok,cursor-kimi; rounds=4; full=2 @ eed055a

Review-Attention: study ~9m (decisions: do-less-alternative, ownership-by-timestamp-inference, aside-suspends-loop, health-cache-shape, app-writes-lb-record, document-external-component-contract; raised: open major) @ eed055a

@dawsontoth dawsontoth added the content 📝 Content specific issues and requests - text, examples, missing info, or clarity label Oct 12, 2026
@dawsontoth
dawsontoth force-pushed the docs/fabric-node-availability branch from 29d62b5 to 5b43cc9 Compare October 12, 2026 21:43
@dawsontoth
dawsontoth changed the base branch from main to learn/administration-production-reliability October 12, 2026 21:43
@dawsontoth
dawsontoth added this pull request to stack #730 October 12, 2026 21:44

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new documentation and guides regarding load balancing, node availability, and taking unhealthy nodes out of rotation in Harper Fabric, complete with a sample JavaScript implementation for an automated availability loop. It also updates the operations API reference to clarify that status records are persisted in the system.hdb_status table and survive restarts. Feedback on the code suggests optimizing the node-checking logic by parsing and comparing hostnames locally to avoid redundant self-requests.

Comment thread learn/developers/taking-a-node-out-of-rotation.mdx Outdated
@Ethan-Arrowood

Copy link
Copy Markdown
Member

Looks to be some conflicts.

@Ethan-Arrowood

Copy link
Copy Markdown
Member

Otherwise great work on this. I like it!

… node out of rotation

Add a Learn guide for applications on Fabric that feed their own health into
the node's availability record, which Fabric's status-check component serves
to the load balancer at GET /status. It covers when to do it, six safety
rules (hysteresis; never undoing Fabric's or an operator's write, tracked by
the record's __updatedtime__ in a non-replicated marker table and re-read
before every write; never taking the last node out; a recheck right after
going out; surviving restarts; warn logging and an off switch), a generic
sample component, a local drill against a throwaway Harper with the real
status-check component and the CLI's harper login, and caveats, including
the narrow windows a set_status without compare-and-swap leaves open.

Add a Fabric page for status-check: what GET /status answers, that POST and
DELETE need a super user, that the record is per node, persisted and not
replicated, and how to take a node out with harper login and harper
set_status, locally or from GitHub Actions with OIDC, as a role whose
operations list names only set_status and get_status (v5.3.0). It warns
not to deploy the @harperdb/status-check npm package on Fabric.

In the set_status reference, say that set_status stores only status, that
Harper core does not act on status values, and that on Fabric the
availability record decides routing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dawsontoth
dawsontoth force-pushed the learn/administration-production-reliability branch from cc7e165 to cc92816 Compare October 14, 2026 01:13
@dawsontoth
dawsontoth force-pushed the docs/fabric-node-availability branch from 189251c to eed055a Compare October 14, 2026 01:13
@dawsontoth
dawsontoth removed this pull request from stack #730 October 14, 2026 18:44
@dawsontoth
dawsontoth merged commit 0f403ab into learn/administration-production-reliability Oct 14, 2026
13 of 14 checks passed
@dawsontoth
dawsontoth deleted the docs/fabric-node-availability branch October 14, 2026 18:44
@github-actions

Copy link
Copy Markdown

🧹 Preview Cleanup

The preview deployment for this PR has been removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

content 📝 Content specific issues and requests - text, examples, missing info, or clarity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants