Skip to content

fix(demo): initialize NATS adapters and add GetPubSubName function#2423

Merged
asoorm merged 1 commit intomainfrom
fix/demo-nats-adapter
Dec 19, 2025
Merged

fix(demo): initialize NATS adapters and add GetPubSubName function#2423
asoorm merged 1 commit intomainfrom
fix/demo-nats-adapter

Conversation

@asoorm
Copy link
Copy Markdown
Contributor

@asoorm asoorm commented Dec 18, 2025

  • Call Startup() on NATS adapters to establish connections
  • Add GetPubSubName function to subgraphs config to prevent nil pointer dereference
  • Fixes "nats client not initialized" error in mood and availability subgraphs

The NATS adapters were being created but not started, leaving the client field uninitialized. This caused mutations that publish to NATS to fail with "nats client not initialized" errors.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added configuration option for customizing PubSub name resolution
  • Bug Fixes

    • Enhanced adapter initialization with proper error handling to ensure adapters are correctly started before use

✏️ Tip: You can customize this high-level summary in your review settings.

- Call Startup() on NATS adapters to establish connections
- Add GetPubSubName function to subgraphs config to prevent nil pointer dereference
- Fixes "nats client not initialized" error in mood and availability subgraphs

The NATS adapters were being created but not started, leaving the client
field uninitialized. This caused mutations that publish to NATS to fail
with "nats client not initialized" errors.
@asoorm asoorm requested review from a team as code owners December 18, 2025 21:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 18, 2025

Walkthrough

The PR adds a GetPubSubName configuration hook field to the subgraphs Config struct and updates its usage in the main configuration file. Additionally, Startup(ctx) initialization calls are added to NATS adapters with error handling to ensure proper initialization before adapter registration.

Changes

Cohort / File(s) Summary
Configuration hook addition
demo/cmd/all/main.go, demo/pkg/subgraphs/...
Added GetPubSubName func(string) string field to Config struct; initialized with an identity function; Config initialization updated to include this field
Adapter startup initialization
demo/pkg/subgraphs/subgraphs.go
Added Startup(ctx) calls for NATS adapters (defaultAdapter and myNatsAdapter) with error wrapping and early returns on failure

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify the Startup() error handling pattern is consistent with the codebase conventions
  • Confirm the GetPubSubName identity function behavior is the intended default implementation
  • Ensure adapter startup ordering does not introduce race conditions or dependency issues

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: initialization of NATS adapters and addition of GetPubSubName function, matching the core objectives and file modifications.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Dec 18, 2025

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-dc50c90f7c0c3f8bb907bf3b0247d845971a696d-nonroot

Copy link
Copy Markdown
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
demo/pkg/subgraphs/subgraphs.go (1)

221-234: Good fix for adapter initialization, but consider cleanup on partial failure.

The Startup(ctx) calls correctly initialize the NATS adapters and address the "nats client not initialized" error mentioned in the PR objectives. The error handling is clear and descriptive.

However, if myNatsAdapter.Startup(ctx) fails after defaultAdapter.Startup(ctx) succeeds, the defaultAdapter connection remains open, creating a resource leak.

🔎 Suggested fix to properly clean up resources on failure
 	if err := defaultAdapter.Startup(ctx); err != nil {
 		return nil, fmt.Errorf("failed to start default nats adapter: %w", err)
 	}
+	defer func() {
+		if err != nil {
+			_ = defaultAdapter.Shutdown(ctx)
+		}
+	}()
 	natsPubSubByProviderID["default"] = defaultAdapter
 
 	myNatsAdapter, err := natsPubsub.NewAdapter(ctx, zap.NewNop(), url, []nats.Option{}, "hostname", "test", datasource.ProviderOpts{
 		StreamMetricStore: rmetric.NewNoopStreamMetricStore(),
 	})
 	if err != nil {
 		return nil, fmt.Errorf("failed to create my-nats adapter: %w", err)
 	}
 	if err := myNatsAdapter.Startup(ctx); err != nil {
 		return nil, fmt.Errorf("failed to start my-nats adapter: %w", err)
 	}
+	defer func() {
+		if err != nil {
+			_ = myNatsAdapter.Shutdown(ctx)
+		}
+	}()
 	natsPubSubByProviderID["my-nats"] = myNatsAdapter

Note: This assumes the adapter has a Shutdown method. Alternatively, you could use a named return value for err and check it in the defer to clean up both adapters if any subsequent operation fails.

🧹 Nitpick comments (1)
demo/pkg/subgraphs/subgraphs.go (1)

83-83: Consider validating GetPubSubName is non-nil.

The new GetPubSubName field is used by the availability and mood subgraphs (lines 196, 200, 273, 276) to resolve PubSub names and prevent nil pointer dereferences in their implementations.

Since this is demo code and main.go always initializes this field, the current implementation is likely acceptable. However, for defensive programming, you might consider adding a nil check in the New function or providing a default implementation if the field is nil.

🔎 Optional: Add defensive nil check
 func New(ctx context.Context, config *Config) (*Subgraphs, error) {
+	if config.GetPubSubName == nil {
+		config.GetPubSubName = func(name string) string { return name }
+	}
 	url := nats.DefaultURL
 	if defaultSourceNameURL := os.Getenv("NATS_URL"); defaultSourceNameURL != "" {
 		url = defaultSourceNameURL
 	}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2173504 and 48810ce.

📒 Files selected for processing (2)
  • demo/cmd/all/main.go (1 hunks)
  • demo/pkg/subgraphs/subgraphs.go (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2172
File: router/core/graph_server.go:0-0
Timestamp: 2025-09-17T20:55:39.456Z
Learning: The Initialize method in router/internal/retrytransport/manager.go has been updated to properly handle feature-flag-only subgraphs by collecting subgraphs from both routerConfig.GetSubgraphs() and routerConfig.FeatureFlagConfigs.ConfigByFeatureFlagName, ensuring all subgraphs receive retry configuration.
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: router/pkg/config/config.schema.json forbids null values for traffic_shaping.subgraphs: additionalProperties references $defs.traffic_shaping_subgraph_request_rule with type "object". Therefore, in core.NewSubgraphTransportOptions, dereferencing each subgraph rule pointer is safe under schema-validated configs, and a nil-check is unnecessary.
Learnt from: dkorittki
Repo: wundergraph/cosmo PR: 2329
File: router/pkg/pubsub/datasource/subscription_event_updater.go:86-88
Timestamp: 2025-11-13T10:10:47.680Z
Learning: In router/pkg/pubsub/datasource/subscription_event_updater.go, the SetHooks method is intentionally designed to only replace hook handlers, not reconfigure timeout or semaphore settings. The timeout and semaphore fields are meant to be set once during construction via NewSubscriptionEventUpdater and remain immutable. If different timeout or concurrency settings are needed, a new updater instance should be created rather than modifying the existing one.
📚 Learning: 2025-09-17T20:55:39.456Z
Learnt from: SkArchon
Repo: wundergraph/cosmo PR: 2172
File: router/core/graph_server.go:0-0
Timestamp: 2025-09-17T20:55:39.456Z
Learning: The Initialize method in router/internal/retrytransport/manager.go has been updated to properly handle feature-flag-only subgraphs by collecting subgraphs from both routerConfig.GetSubgraphs() and routerConfig.FeatureFlagConfigs.ConfigByFeatureFlagName, ensuring all subgraphs receive retry configuration.

Applied to files:

  • demo/cmd/all/main.go
  • demo/pkg/subgraphs/subgraphs.go
📚 Learning: 2025-08-20T10:08:17.857Z
Learnt from: endigma
Repo: wundergraph/cosmo PR: 2155
File: router/core/router.go:1857-1866
Timestamp: 2025-08-20T10:08:17.857Z
Learning: router/pkg/config/config.schema.json forbids null values for traffic_shaping.subgraphs: additionalProperties references $defs.traffic_shaping_subgraph_request_rule with type "object". Therefore, in core.NewSubgraphTransportOptions, dereferencing each subgraph rule pointer is safe under schema-validated configs, and a nil-check is unnecessary.

Applied to files:

  • demo/cmd/all/main.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
  • GitHub Check: image_scan (nonroot)
  • GitHub Check: image_scan
  • GitHub Check: integration_test (./telemetry)
  • GitHub Check: build_test
  • GitHub Check: integration_test (./events)
  • GitHub Check: integration_test (./. ./fuzzquery ./lifecycle ./modules)
  • GitHub Check: build_push_image
  • GitHub Check: build_push_image (nonroot)
🔇 Additional comments (1)
demo/cmd/all/main.go (1)

40-42: LGTM! Identity function appropriately implements the GetPubSubName hook.

The identity function implementation is clean and appropriate for the demo context. It ensures the GetPubSubName field is always set, preventing nil pointer dereferences in the availability and mood subgraphs.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.35%. Comparing base (e647984) to head (48810ce).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2423      +/-   ##
==========================================
- Coverage   61.55%   61.35%   -0.20%     
==========================================
  Files         229      229              
  Lines       23814    23814              
==========================================
- Hits        14658    14612      -46     
- Misses       7919     7970      +51     
+ Partials     1237     1232       -5     

see 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@asoorm asoorm merged commit cfffbce into main Dec 19, 2025
30 of 31 checks passed
@asoorm asoorm deleted the fix/demo-nats-adapter branch December 19, 2025 09:18
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