Skip to content

Comments

Open Introduce support for liveness check for MSSQL CDC listener#1245

Merged
gayaldassanayake merged 4 commits intomainfrom
cdc-islive
Feb 18, 2026
Merged

Open Introduce support for liveness check for MSSQL CDC listener#1245
gayaldassanayake merged 4 commits intomainfrom
cdc-islive

Conversation

@gayaldassanayake
Copy link
Contributor

@gayaldassanayake gayaldassanayake commented Feb 17, 2026

Purpose

$ subject

Examples

Checklist

  • Linked to an issue
  • Updated the changelog
  • Added tests
  • Updated the spec
  • Checked native-image compatibility

Summary

This pull request adds liveness-check support for the MSSQL CDC listener, enabling applications to determine whether a CDC listener instance is active and receiving events.

Key changes

  • Core functionality

    • Added liveness support by introducing a livenessInterval configuration and wiring it into the listener configuration.
    • Broadened the listener config field from map to map to allow more flexible configuration values.
    • Refactored internal configuration handling to populate Debezium and database properties into a unified config map that includes the liveness setting.
  • Tests

    • Added four tests validating liveness behavior:
      • Listener reports offline before start
      • Listener reports online after start
      • Listener reports offline after graceful stop
      • Listener reports offline when no events are received within the configured interval
  • Dependency and build updates

    • Bumped module and related package versions (including the CDC and PostgreSQL module entries) and updated native jar and compiler plugin paths to the new version.
    • Added and updated supporting libraries for Avro, Kafka and Confluent tooling, plus new stdlib dependencies (e.g., log, uuid) to support the expanded CDC functionality.
    • Updated Gradle and dependency manifests to reflect new/updated package versions.

Impact

Provides standardized liveness observability for MSSQL CDC listeners, improving operational monitoring and allowing callers to detect inactive or stopped listeners programmatically. Existing public APIs remain unchanged aside from the config type relaxation described above.

@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Bumps multiple package versions (including PostgreSQL from 1.16.2→1.16.3), adds Avro/Kafka/Confluent/UUID/log packages, changes CdcListener.config type from map<string> to map<anydata> and adds livenessInterval handling, and adds liveness tests for the CDC listener.

Changes

Cohort / File(s) Summary
PostgreSQL Version Update
ballerina/Ballerina.toml, ballerina/CompilerPlugin.toml
Bump postgresql package and native/compiler-plugin JAR references from 1.16.2 to 1.16.3 (paths updated to -1.16.3-SNAPSHOT).
Dependency Manifest & Versions
ballerina/Dependencies.toml, gradle.properties
Multiple stdlib/package version updates (crypto, data.jsondata, observe, os, time, cdc, postgresql) and removal of testOnly scope for lang.__internal.
New Standard Libraries Added
ballerina/Dependencies.toml, gradle.properties, build.gradle
Add packages and gradle properties for avro, lang.int, log, uuid, plus Confluent-related packages: confluent.cavroserdes, confluent.cregistry, and kafka; add corresponding stdlib version properties and Gradle dependencies.
CDC Listener Change
ballerina/cdc_listener.bal
Change CdcListener field type from map<string> & readonly to map<anydata> & readonly; rename local config map to debeziumConfigs, populate Debezium and DB configs there, and add livenessInterval into the final listener config.
Liveness Tests Added
ballerina/tests/listener_liveness_test.bal
Add four tests covering listener liveness: before start, while started, after stop, and without receiving events (uses cdc:isLive assertions).

Sequence Diagram(s)

sequenceDiagram
    participant Test
    participant CdcListener
    participant Debezium
    participant PostgresDB

    Test->>CdcListener: create(listenerConfig with livenessInterval?)
    CdcListener->>Debezium: build debeziumConfigs (includes DB + livenessInterval)
    CdcListener->>Debezium: start listener
    Debezium->>PostgresDB: subscribe / stream events
    Note right of Debezium: events flow or no events
    Test->>CdcListener: cdc:isLive()
    CdcListener->>Test: return true/false based on livenessInterval & event activity
    Test->>CdcListener: stop()
    CdcListener->>Debezium: stop subscription
    Debezium->>PostgresDB: unsubscribe
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰
I hopped through configs, versions tall and spry,
Avro, Kafka, Confluent — new friends nearby.
Listener learned to count its heartbeat's song,
Liveness checked, start, stop — all righted along.
A tiny rabbit cheers this tidy supply.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete with placeholder text '$ subject' instead of actual purpose, and all checklist items are unchecked despite tests being added and dependencies updated. Replace '$ subject' placeholder with clear purpose description, update checklist to reflect completed tasks (tests added, dependencies updated), and provide concrete examples of liveness check usage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title describes supporting liveness checks for MSSQL CDC listener, which aligns with the changes that introduce liveness interval, update CdcListener config, and add liveness-related tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cdc-islive

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
ballerina/tests/listener_liveness_test.bal (1)

88-107: Consider adding a test for liveness recovery after receiving events.

The current testLivenessWithoutReceivingEvents test validates that liveness becomes false when no events are received within the interval. For completeness, consider adding a complementary test that verifies liveness returns to true when events are received again after a period of inactivity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ballerina/tests/listener_liveness_test.bal` around lines 88 - 107, Add a
complementary test (e.g., testLivenessRecoveryAfterReceivingEvents) that mirrors
testLivenessWithoutReceivingEvents but verifies liveness returns true after
events resume: create a CdcListener with a short livenessInterval, attach it to
testService and start it (use postgresqlListener.attach and
postgresqlListener.'start()), wait until cdc:isLive(postgresqlListener) becomes
false (use runtime:sleep and cdc:isLive), then simulate/send an event to the
service so the listener receives data, wait a short period and assert
cdc:isLive(postgresqlListener) is true, and finally call
postgresqlListener.gracefulStop(); ensure the test references the same symbols
(CdcListener, livenessInterval, testService, cdc:isLive, gracefulStop) so it
follows the existing pattern.
gradle.properties (1)

63-63: Snapshot dependency for CDC module may cause build reproducibility issues.

The stdlibCdcVersion uses a timestamped snapshot version (1.2.0-20260213-180200-2268a4d). Before merging, ensure this is updated to a stable release version to avoid:

  • Non-reproducible builds
  • Potential breakage if the snapshot artifact is removed from the repository
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gradle.properties` at line 63, The gradle property stdlibCdcVersion is set to
a timestamped snapshot (1.2.0-20260213-180200-2268a4d) which harms
reproducibility; update the stdlibCdcVersion property to a stable released
version (replace the snapshot string with the corresponding released version
tag, e.g., 1.2.0 or the exact stable release your project depends on) so builds
no longer rely on ephemeral snapshot artifacts and ensure any consumers or
dependency constraints (build scripts that reference stdlibCdcVersion) are
updated accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ballerina/tests/listener_liveness_test.bal`:
- Around line 24-39: The test attaches testService to postgresqlListener but
never detaches or stops it; update testLivenessBeforeListenerStart to always
clean up by detaching the service (and stopping the listener if applicable). Add
a deferred/cleanup block after creating postgresqlListener that calls
postgresqlListener.detach(testService) (and postgresqlListener.stop() if the
listener API exposes stop/close) and handle/propagate any errors consistently
(use check or swallow with ignore) so resources are released even on test
failures.

---

Nitpick comments:
In `@ballerina/tests/listener_liveness_test.bal`:
- Around line 88-107: Add a complementary test (e.g.,
testLivenessRecoveryAfterReceivingEvents) that mirrors
testLivenessWithoutReceivingEvents but verifies liveness returns true after
events resume: create a CdcListener with a short livenessInterval, attach it to
testService and start it (use postgresqlListener.attach and
postgresqlListener.'start()), wait until cdc:isLive(postgresqlListener) becomes
false (use runtime:sleep and cdc:isLive), then simulate/send an event to the
service so the listener receives data, wait a short period and assert
cdc:isLive(postgresqlListener) is true, and finally call
postgresqlListener.gracefulStop(); ensure the test references the same symbols
(CdcListener, livenessInterval, testService, cdc:isLive, gracefulStop) so it
follows the existing pattern.

In `@gradle.properties`:
- Line 63: The gradle property stdlibCdcVersion is set to a timestamped snapshot
(1.2.0-20260213-180200-2268a4d) which harms reproducibility; update the
stdlibCdcVersion property to a stable released version (replace the snapshot
string with the corresponding released version tag, e.g., 1.2.0 or the exact
stable release your project depends on) so builds no longer rely on ephemeral
snapshot artifacts and ensure any consumers or dependency constraints (build
scripts that reference stdlibCdcVersion) are updated accordingly.

Comment on lines +24 to +39
function testLivenessBeforeListenerStart() returns error? {
CdcListener postgresqlListener = new ({
database: {
username: cdcUsername,
password: cdcPassword,
port: cdcPort,
databaseName: cdcDatabase
},
options: {
snapshotMode: cdc:NO_DATA
}
});
check postgresqlListener.attach(testService);
boolean liveness = check cdc:isLive(postgresqlListener);
test:assertFalse(liveness, "Liveness check passes even before listener starts");
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing listener cleanup in testLivenessBeforeListenerStart.

The test attaches a service to the listener but never detaches or stops it. While the listener was never started, it's good practice to clean up attached resources to prevent potential side effects on subsequent tests.

🧹 Proposed fix to add cleanup
     check postgresqlListener.attach(testService);
     boolean liveness = check cdc:isLive(postgresqlListener);
     test:assertFalse(liveness, "Liveness check passes even before listener starts");
+    check postgresqlListener.detach(testService);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function testLivenessBeforeListenerStart() returns error? {
CdcListener postgresqlListener = new ({
database: {
username: cdcUsername,
password: cdcPassword,
port: cdcPort,
databaseName: cdcDatabase
},
options: {
snapshotMode: cdc:NO_DATA
}
});
check postgresqlListener.attach(testService);
boolean liveness = check cdc:isLive(postgresqlListener);
test:assertFalse(liveness, "Liveness check passes even before listener starts");
}
function testLivenessBeforeListenerStart() returns error? {
CdcListener postgresqlListener = new ({
database: {
username: cdcUsername,
password: cdcPassword,
port: cdcPort,
databaseName: cdcDatabase
},
options: {
snapshotMode: cdc:NO_DATA
}
});
check postgresqlListener.attach(testService);
boolean liveness = check cdc:isLive(postgresqlListener);
test:assertFalse(liveness, "Liveness check passes even before listener starts");
check postgresqlListener.detach(testService);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ballerina/tests/listener_liveness_test.bal` around lines 24 - 39, The test
attaches testService to postgresqlListener but never detaches or stops it;
update testLivenessBeforeListenerStart to always clean up by detaching the
service (and stopping the listener if applicable). Add a deferred/cleanup block
after creating postgresqlListener that calls
postgresqlListener.detach(testService) (and postgresqlListener.stop() if the
listener API exposes stop/close) and handle/propagate any errors consistently
(use check or swallow with ignore) so resources are released even on test
failures.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.57%. Comparing base (554a6ae) to head (02e9f4e).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1245      +/-   ##
============================================
- Coverage     81.62%   81.57%   -0.05%     
+ Complexity      864      863       -1     
============================================
  Files            28       28              
  Lines          3521     3523       +2     
  Branches        484      484              
============================================
  Hits           2874     2874              
- Misses          431      432       +1     
- Partials        216      217       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gayaldassanayake gayaldassanayake merged commit 51bddda into main Feb 18, 2026
7 of 8 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