• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bedrock-kv / bedrock / 556aeeac68b301d8150b210001e11c75c615490b
82%

Build:
DEFAULT BRANCH: develop
Ran 28 Aug 2026 01:49PM UTC
Jobs 1
Files 213
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

28 Aug 2026 01:48PM UTC coverage: 79.965% (+0.1%) from 79.836%
556aeeac68b301d8150b210001e11c75c615490b

push

github

web-flow
Watch hosted workers, so a dead one stops being reported as running (#222)

Closes bedrock-z2e, under epic bedrock-gu0.

A worker's health was recorded once, when it started, and never
revisited. Nothing monitored the process, so `{:ok, pid}` outlived the
process it named — and there was no monitor, no `trap_exit` and no
`:DOWN` clause anywhere under `service/foreman`: the catch-all
`handle_info/2` would have swallowed one regardless.

That stale value is load-bearing in three places:

| consumer | consequence |
|---|---|
| `do_relay_tsl/2` | layout pushes go to a dead pid — and that push is
how a worker learns it has been **displaced** |
| `do_get_all_running_services/1` | the coordinator keeps being told a
dead process is an available service |
| the health verdict | a fold over these values, so the foreman reports
`:ok` while hosting a corpse |

The third is what made the verdict settled in #218/#219 untrustworthy.
The second was not in the ticket — my failing tests found it.

### The interesting part: `:stopped` is not simply the right answer

Workers are `:transient`, so an abnormal exit is **restarted** under the
same OTP name. Marking a dead worker `:stopped` and leaving it there
would drop a *live* worker out of the roll call — trading a
dead-process-reported-running bug for a live-process-reported-gone bug.

Adopting the replacement at `:DOWN` time doesn't work either: the
`:DOWN` is delivered the instant the process dies, while the supervisor
must first handle its own `EXIT`. It lost that race in every test run.
So adoption is a bounded recheck on a timer, and only a worker still
`:stopped` is adopted — it can never overwrite health the worker
reported for itself.

### What the audit caught, and why my tests missed it

There are **two** adopters, not one. A worker that reports its own
health names a pid, and that report can name a different process than
the one being watched: Olivine's replacement casts `{:ok, self()}` as
soon as startup com... (continued)

36 of 41 new or added lines in 3 files covered. (87.8%)

3 existing lines in 1 file now uncovered.

6937 of 8675 relevant lines covered (79.97%)

1036.84 hits per line

Uncovered Changes

Lines Coverage ∆ File
3
87.86
4.52% lib/bedrock/service/foreman/impl.ex
2
40.63
40.63% lib/bedrock/service/foreman/server.ex

Coverage Regressions

Lines Coverage ∆ File
3
70.11
-3.45% lib/bedrock/data_plane/resolver/tree.ex
Jobs
ID Job ID Ran Files Coverage
1 556aeeac68b301d8150b210001e11c75c615490b.1 28 Aug 2026 01:49PM UTC 213
79.97
GitHub Action Run
Source Files on build 556aeeac68b301d8150b210001e11c75c615490b
  • Tree
  • List 213
  • Changed 4
  • Source Changed 0
  • Coverage Changed 4
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • 556aeeac on github
  • Prev Build on develop (#61DAE68F...)
  • Next Build on develop (#3092A6F8...)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc