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

kibertoad / layered-loader / 28658774958
98%

Build:
DEFAULT BRANCH: main
Ran 03 Jul 2026 11:53AM UTC
Jobs 1
Files 28
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

03 Jul 2026 11:52AM UTC coverage: 98.344% (-0.2%) from 98.545%
28658774958

push

github

web-flow
Fix race conditions and correctness issues in caching layers (#417)

* Fix race conditions and correctness issues in caching layers

Synthesizes PR #414 (invalidation/in-flight race audit) and PR #415
(correctness audit), combining best-of-breed fixes from both.

Race conditions between invalidation and in-flight loads:
- getAsyncOnly (flat + group) fences its write-back: the resolved value is
  persisted only if the dedup entry still belongs to that load, so any
  invalidation or forced write that evicted the entry cancels the write-back
  while awaiting callers still receive the value.
- Invalidation paths (invalidateCache/invalidateCacheFor/invalidateCacheForMany/
  invalidateCacheForGroup) evict running loads before and after the awaited
  async delete and clear the in-memory entry last, so a get racing a slow async
  delete cannot repopulate memory after the invalidation resolves.
- deleteGroupRunningLoad only drops the group entry when it still points at the
  settling load's map, so a load settling against a stale map cannot evict a
  newer load's map and break deduplication.

Correctness fixes:
- InMemoryCache.getMany / InMemoryGroupCache.getManyFromGroup treated cached
  falsy values (0, '', false, null) as misses via a truthy check; use an
  undefined check instead, consistent with single get and RedisCache.
- InMemoryGroupCache reads (getFromGroup, getManyFromGroup,
  getExpirationTimeFromGroup, deleteFromGroup) no longer insert empty groups
  into the LRU on a miss, which could evict a populated group's still-valid data.
- Loader/GroupLoader preemptive-refresh expiration lookups now have a .catch, so
  an async-cache error no longer becomes an unhandled promise rejection.
- RedisGroupCache.deleteGroup expires the group index with groupTtlInMsecs
  instead of the entry ttlInMsecs, consistent with setForGroup/setManyForGroup.

Redis notification consumers:
- Register the message listener before subscribing, so no message is dropped in
  the ... (continued)

403 of 422 branches covered (95.5%)

Branch coverage included in aggregate %.

94 of 94 new or added lines in 10 files covered. (100.0%)

725 of 725 relevant lines covered (100.0%)

120.66 hits per line

Jobs
ID Job ID Ran Files Coverage
1 28658774958.1 03 Jul 2026 11:53AM UTC 28
98.34
GitHub Action Run
Source Files on build 28658774958
  • Tree
  • List 28
  • Changed 10
  • Source Changed 10
  • Coverage Changed 10
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #28658774958
  • 7ff9ec0a on github
  • Prev Build on main (#28654852281)
  • Next Build on main (#28662275514)
  • 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