Skip to content

fix: stop persisting CDC processor read marker across restarts - #20

Merged
pallakartheekreddy merged 1 commit into
Sunbird-Knowlg:mainfrom
divyagovindaiah:fix/cdc-processor-marker-persistence
Aug 17, 2026
Merged

fix: stop persisting CDC processor read marker across restarts#20
pallakartheekreddy merged 1 commit into
Sunbird-Knowlg:mainfrom
divyagovindaiah:fix/cdc-processor-marker-persistence

Conversation

@divyagovindaiah

@divyagovindaiah divyagovindaiah commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

GraphLogProcessor.init() registers the transaction-log processor with setProcessorIdentifier("janusgraph-cdc-processor"). An identified log processor persists its read marker in JanusGraph and resumes from it on every subsequent restart — silently ignoring setStartTime() after the very first run.

Root cause

Every JanusGraph stop/start replays old/backlogged transaction-log entries because of the persisted marker. Vertex property lookups (e.g. IL_FUNC_OBJECT_TYPE) performed on vertex handles bound to a replayed historical transaction come back empty — this appears to be a JanusGraph/storage-backend limitation when reading properties outside the specific transaction's own change-set. SunbirdLegacyMessageConverter falls back to vertex.label() (JanusGraph's generic "vertex" label) when that lookup is empty, which then hits the existing filter:

if ("vertex".equalsIgnoreCase(objectType)) {
    logger.debug("Skipping event for vertex {} with objectType='vertex' (no IL_FUNC_OBJECT_TYPE set)", vertex.id());
    return null;
}

Net effect: after any JanusGraph restart, every backlogged event is filtered out, and CDC silently stops producing anything until the backlog fully drains (which itself takes a long time and can appear to "never recover" on clusters with a large accumulated transaction-log history, e.g. after a disaster-recovery restore).

Reproduced and confirmed via debug logging on a live cluster: the marker loaded on restart showed Loaded identified ReadMarker start time <stale timestamp> instead of now, and every processed message hit Event filtered by converter for node <id> — 100% filter rate, including on messages only minutes old (i.e. not a formatting/legacy-data issue, purely a replay-vs-live distinction).

Fix

Remove .setProcessorIdentifier(...). Without an identifier, the log processor never persists a marker, so it always starts fresh from setStartTime() (now - 1 minute) on every restart. This trades replaying the exact outage window for CDC actually continuing to work after a restart — the correct tradeoff for a live content-indexing pipeline where a live/current pipeline matters more than a complete historical replay.

Test plan

  • Deploy to a test JanusGraph instance with the CDC extension enabled
  • Create/update content, confirm CDC event appears in the configured sink
  • Stop and restart the JanusGraph pod
  • Create/update new content immediately after restart, confirm the event still appears (this is the case that was broken before this fix)
  • Confirm no persisted marker is created for janusgraph-cdc-processor in the backend after this change

Summary by CodeRabbit

  • Bug Fixes
    • Improved change-data-capture recovery after restarts.
    • CDC now replays events from the configured start time instead of resuming from a persisted read position, helping prevent missed backlog events.

setProcessorIdentifier("janusgraph-cdc-processor") makes JanusGraph persist
a durable read marker and resume from it on every subsequent restart,
silently ignoring setStartTime() after the very first run.

This means every JanusGraph stop/start replays old/backlogged
transaction-log entries. Vertex property lookups on those replayed
entries come back empty (a JanusGraph/storage limitation on log-replay
transaction handles), so SunbirdLegacyMessageConverter falls back to
objectType="vertex" for every backlogged event and filters it out via
the "no IL_FUNC_OBJECT_TYPE set" check. Net effect: CDC silently stops
emitting any events after a restart, until the backlog fully drains.

Removing the processor identifier means the log processor never persists
a marker, so it always starts fresh from setStartTime() (now - 1 minute)
on every restart — trading replay of the outage window for CDC actually
working after a restart, which is the correct tradeoff for a live
content-indexing pipeline.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67d19d32-f22f-4b51-b5f9-266a15e7d26a

📥 Commits

Reviewing files that changed from the base of the PR and between 6acd451 and ad918b9.

📒 Files selected for processing (1)
  • janusgraph-cdc-extension/src/main/java/org/sunbird/janusgraph/cdc/GraphLogProcessor.java

📝 Walkthrough

Walkthrough

GraphLogProcessor now registers the CDC log processor without a persistent processor identifier, so initialization starts replay from the configured start time instead of resuming a persisted read marker.

Changes

CDC restart behavior

Layer / File(s) Summary
Processor registration and replay behavior
janusgraph-cdc-extension/src/main/java/org/sunbird/janusgraph/cdc/GraphLogProcessor.java
GraphLogProcessor registers the log processor using only LOG_IDENTIFIER and documents that restarts begin from the configured setStartTime().

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: stopping CDC read-marker persistence across restarts.
Description check ✅ Passed It covers the summary, root cause, fix, and testing plan; the issue reference and dependency list are the main omissions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pallakartheekreddy
pallakartheekreddy merged commit a35f455 into Sunbird-Knowlg:main Aug 17, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants