Repository navigation
Add cluster mode support to OCL providers - #373
italomacedo wants to merge 7 commits into
Conversation
Make the OCL code system and value set providers cluster-aware, following the same leader/follower pattern the VSAC provider already uses. Leader (master): runs discovery, refresh cycles, background warm-up jobs, and writes the cold cache atomically (temp file + rename). Follower (tx-worker): never fetches from OCL for discovery or bulk downloads. Loads from cold-cache files and watches for file changes (mtime) to reload when the leader updates a cache file. Key changes: - Atomic cache writes via temp-file-then-rename (benefits all modes) - Cluster role threaded through role.js -> tx.js -> library.js -> OCL configs - OCLCodeSystemProvider: followers discover from cold cache, skip API calls - OCLValueSetProvider: followers skip collection discovery and expansion - OCLSourceCodeSystemFactory: followers skip background loads, reload on mtime - Mtime-based cache invalidation for followers (no IPC needed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks, this is the right direction. The master downloads from OCL and writes the cache files, and the workers read them, the same split we use for VSAC. Making the cache writes atomic is worth having whatever else happens. But I can't merge it yet: as it stands, a worker can't serve any OCL code system's concepts. Workers get no OCL code system providers. Even with providers, workers would answer differently from the master:
Nothing is warmed unless the master is asked. The master only fetches a code system's content when a request on the master misses it. With What I'd suggest:
Smaller things:
The existing OCL and library tests pass on the branch. |
Address Grahame's review feedback on the follower initialization path: - Master writes a discovery snapshot file (all source metas + CodeSystem JSON) after each discovery/refresh, so followers get identical metadata - Followers build metas/providers from the snapshot file (same IDs, caseSensitive, publisher, description as master) instead of minimal CodeSystem objects from cold cache - Master proactively warms all discovered sources after discovery - Remove redundant tx.oclCluster from role.js (kept only in tx.js) - Pass cluster role explicitly to factory constructor instead of static - Fix VS follower cache check to use actual params key, not just 'default' - Clean up stale .tmp.<pid> files at startup - Add follower test suite (7 tests) - Update cluster.md with OCL row and paragraph Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
I'd hoped to approve this one, but it isn't quite ready yet. The snapshot approach fixes the main problem from my last review: workers now have the same providers, ids and metadata as the master. Thanks for working through the rest of the list too. But the rework has introduced some new problems. 1. The snapshot file carries every concept, and is rewritten every minute. Once a code system is complete,
2. Proactive warm-up needs a limit. I asked for the master to download every source after discovery. Seeing it implemented, I don't think it can be unconditional:
Please limit it to cluster mode, or to configured organisations, or make it a setting. Separately, the warm-up in 3. A worker can delete the master's in-progress write. 4. Workers still don't learn about OCL value sets. Workers skip collection discovery, so they know only the value sets that had a cold-cache file when they started. 5. The tests write to the real data folder. The cache paths come from For reference: it merges cleanly onto main, the OCL and library tests pass, and lint is clean. |
…solation - Strip concept arrays from CS discovery snapshot to reduce size - Use SHA-256 hash to skip snapshot rewrites when content is unchanged - Guard proactive warm-up to run only in cluster mode - Restrict stale tmp file cleanup to leader/single-process only - Add VS discovery snapshot so followers learn about value sets - Make OCL cache dir overridable via OCL_CACHE_DIR env var - Update tests to use a temp folder instead of real data directory Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks Italo — this is much closer. Items 1 and 3 are resolved, and the VS discovery snapshot is the right approach for 4. Remaining: Test isolation (5): only ocl-cluster-follower.test.js uses a temp OCL_CACHE_DIR. ocl-cs-default-version, ocl-factory-discovery, ocl-discovery-global and ocl-vs-resolve-reference still write discovery-snapshot.json / vs-discovery-snapshot.json (plus codesystems/ and valuesets/) into data/terminology-cache/ocl. A real follower will pick these up. Suggest setting OCL_CACHE_DIR to a temp dir for the whole OCL suite, e.g. in a jest setupFiles for tests/ocl, before any module is required. |
… docs - Move OCL_CACHE_DIR setup to shared jest setup files so ALL OCL tests use a temp folder, not just the follower tests - Add VS snapshot check to fetchValueSet and searchValueSets so followers that start before the leader discover new value sets - Document warm-up scope and VS snapshot in cluster.md - Add follower VS discovery snapshot tests - Add snapshot hash deduplication test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Thanks Italo, this is very close now. Test isolation, the value set snapshot check on fetch and search, and the note about warm-up scope in cluster.md are all done, and the snapshot changes from the earlier rounds hold up. A last few things, and then I'll merge:
And for later, not this PR: the OCL cache folder is |
…kage-lock - Fix hash dedup test: use mocked leader HTTP client to properly verify that unchanged sources don't rewrite the discovery snapshot - Add VS snapshot check to fetchValueSetById (was missing) - Store VS snapshot check promise so tests can await it instead of using fixed setTimeout sleeps - Replace all fixed sleeps with _refreshPromise / _vsSnapshotCheckPromise awaits in follower tests - Revert package-lock.json to main (mongoose/saslprep bumps already merged) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Add cluster mode support to OCL providers (CodeSystem, ValueSet, ConceptMap) following the existing VSAC leader/follower pattern.
How it works
Master (leader): Discovers sources from OCL, resolves default versions, writes a discovery snapshot (
data/terminology-cache/ocl/discovery-snapshot.json) containing full source metadata and CodeSystem JSON. After each discovery/refresh cycle, proactively warms all sources into per-source cold cache files. All writes use atomic temp-file-plus-rename.Workers (followers): Read the discovery snapshot to build identical providers and factories (same IDs,
caseSensitive,publisher,description, filters, properties as master). Load concepts from per-source cold cache files. Detect snapshot changes on the once-per-minute refresh cycle and create factories for newly discovered sources. Can still fetch individual concepts on demand for cache misses, but never run bulk discovery or background warm-up.Changes
tx/ocl/cs-ocl.cjs: Discovery snapshot write/read/deserialize, follower loads from snapshot instead of scanning cold cache, proactive warm-up after discovery, cluster passed explicitly to factory constructortx/ocl/vs-ocl.cjs: Fix follower cache check to use actual params key (not just'default'), stale tmp cleanuptx/ocl/cache/cache-paths.cjs: AddDISCOVERY_SNAPSHOT_PATHtx/ocl/cache/cache-utils.cjs: AddcleanupStaleTmpFilestx/library.js: Pass cluster role to factory constructorlibrary/role.js: Remove redundanttx.oclCluster(kept only thetx.jsderivation)cluster.md: Add OCL row to "What runs where" table and OCL paragraphtests/ocl/ocl-cluster-follower.test.js: 7 tests for follower initialization, metadata preservation, snapshot reloadTest plan
--role=masterand verify discovery snapshot is written--role=tx-workerand verify workers serve OCL code systems with correct metadata🤖 Generated with Claude Code