Skip to content

Conversation

@wolf31o2
Copy link
Member

@wolf31o2 wolf31o2 commented Dec 2, 2025


Summary by cubic

Set the default data directory to ".dingo" for the Badger blob and SQLite metadata plugins, with programmatic overrides via SetPluginOption (used in database.New). This ensures predictable local storage and lets tests or configs choose per-run dirs or in-memory mode.

Written for commit 930411a. Summary will update automatically on new commits.

Summary by CodeRabbit

  • New Features

    • Programmatic plugin option overrides for tests
    • Plugin registration API to register available plugins
  • Documentation

    • Added guidance and examples for overriding plugin options in tests, with per-test temporary directories
  • Configuration

    • Default storage directory set to ".dingo" for blob and metadata plugins
    • Directory creation now uses stricter permissions for on-disk storage
  • Tests

    • New tests validating option overrides, type checks, and isolated test data dirs

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

@wolf31o2 wolf31o2 requested a review from a team as a code owner December 2, 2025 23:26
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 2, 2025

📝 Walkthrough

Walkthrough

Adds programmatic plugin configuration and test isolation support. New public APIs in the plugin package: Register(pluginEntry) to append entries to the global plugin registry and SetPluginOption(pluginType, pluginName, optionName, value) to override plugin option destinations before plugin instantiation with runtime type checks. database.New now copies the config and calls SetPluginOption to apply DataDir into blob and metadata plugin options. Default data-dir for the Badger (blob) and SQLite (metadata) plugins changed from empty to ".dingo". Tests and the integration harness set per-test temporary data directories and were updated to use config default plugin identifiers. Documentation PLUGIN_DEVELOPMENT.md gained a section documenting programmatic option overrides for tests. Several struct field reorderings and directory-permission changes (to 0o755) were also applied.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review SetPluginOption: registry lookup, option discovery, pointer/type assertions, nil-pointer checks, and error semantics (including no-op for unknown option).
  • Verify Register: appending to global pluginEntries and the non-thread-safety comment.
  • Inspect database.New modifications: config copy semantics, timing of SetPluginOption calls, and error propagation.
  • Check tests (database/plugin/plugin_test.go, internal/integration/*): global plugin-state mutation, use of t.TempDir/TestMain, and potential for test order or concurrency flakiness.
  • Validate default data-dir changes in badger and sqlite and filesystem permission changes (0o755) for platform implications.
  • Spot-check struct field reorders (connmanager, blob/aws, sqlite, etc.) for any reflection/ABI impacts.

Possibly related PRs

Pre-merge checks and finishing touches

✅ 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 and concisely summarizes the primary change: setting a default data directory to '.dingo' for database storage plugins.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/default-data-dir

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 836dfbb and 930411a.

📒 Files selected for processing (14)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • connmanager/connection_manager.go (2 hunks)
  • database/database.go (3 hunks)
  • database/plugin/blob/aws/database.go (1 hunks)
  • database/plugin/blob/badger/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/blob/gcs/plugin_test.go (1 hunks)
  • database/plugin/metadata/sqlite/database.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • database/plugin/register.go (1 hunks)
  • internal/integration/benchmark_test.go (3 hunks)
  • internal/integration/integration_test.go (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • database/plugin/metadata/sqlite/plugin.go
  • PLUGIN_DEVELOPMENT.md
  • database/plugin/register.go
  • database/plugin/metadata/sqlite/database.go
  • database/plugin/blob/gcs/plugin_test.go
  • internal/integration/benchmark_test.go
  • database/plugin/blob/badger/database.go
🧰 Additional context used
🧬 Code graph analysis (4)
database/plugin/plugin.go (2)
database/plugin/register.go (2)
  • PluginType (24-24)
  • PluginTypeName (31-40)
database/plugin/option.go (4)
  • PluginOptionTypeString (29-29)
  • PluginOptionTypeBool (30-30)
  • PluginOptionTypeInt (31-31)
  • PluginOptionTypeUint (32-32)
database/database.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (2)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
internal/integration/integration_test.go (3)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (3)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
  • GetPlugin (115-124)
internal/config/config.go (2)
  • DefaultBlobPlugin (50-50)
  • DefaultMetadataPlugin (51-51)
database/plugin/plugin_test.go (3)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (2)
  • PluginTypeMetadata (27-27)
  • PluginTypeBlob (28-28)
internal/config/config.go (2)
  • DefaultMetadataPlugin (51-51)
  • DefaultBlobPlugin (50-50)
⏰ 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). (7)
  • GitHub Check: go-test (1.25.x, macos-latest)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: Analyze (go)
  • GitHub Check: nilaway
🔇 Additional comments (14)
database/plugin/blob/aws/database.go (1)

33-43: LGTM!

The struct field reordering is a cosmetic change that improves field organization by placing startupCancel closer to related context/client fields. No behavioral impact.

connmanager/connection_manager.go (1)

37-56: LGTM!

Struct field reorderings across connectionInfo, ConnectionManager, and ConnectionManagerConfig are cosmetic changes that improve field organization without affecting behavior.

database/plugin/blob/badger/plugin.go (2)

46-46: LGTM!

Setting the default dataDir to .dingo aligns with the PR objective of providing a predictable local storage path.


63-63: Ensure DefaultValue and runtime default remain synchronized.

The DefaultValue: ".dingo" matches the runtime default set in initCmdlineOptions(). This is good for consistency. Note that .dingo is a relative path, so the directory will be created in the current working directory at runtime.

database/database.go (2)

127-129: Good defensive copy to avoid mutating the caller's config.

Creating a shallow copy of the config prevents unintended side effects on the caller's original config object.


141-161: Acknowledged global state mutation with appropriate documentation.

The comments clearly document that SetPluginOption mutates global plugin state and is not concurrency-safe. This is an acceptable trade-off for the initialization-time configuration pattern used here. Multiple concurrent Database.New() calls in the same process could interfere, but this aligns with typical single-initialization usage.

database/plugin/plugin.go (3)

67-77: Comprehensive documentation of initialization constraints.

The comments clearly explain:

  1. Single-threaded/initialization-only access pattern for pluginEntries
  2. Direct writes to plugin option destinations require pre-instantiation calls
  3. This addresses the previous review feedback about synchronization

These constraints are acceptable for the intended use case (configuration before plugin startup).


94-223: Robust type-checked assignment with proper nil handling.

The implementation correctly:

  • Validates input value types before assignment
  • Checks opt.Dest for nil
  • Validates destination pointer types via type assertion
  • Checks for nil destination pointers after assertion
  • Handles PluginOptionTypeUint with both uint64 and int (with negative check)

This addresses the previous review feedback about potential nil pointer dereferences.


225-228: Sensible non-fatal behavior for unknown options.

Returning nil for unknown options allows callers to attempt setting options that may not exist for all plugin implementations (e.g., data-dir for cloud plugins). This is well-documented in the comment.

database/plugin/plugin_test.go (1)

13-56: Good test coverage for SetPluginOption API.

The test covers key scenarios:

  • Success paths for string, uint64, and bool options
  • Type mismatch error detection
  • Non-fatal behavior for unknown options
  • Error for nonexistent plugins

The comment on lines 14-16 appropriately notes the global state mutation caveat. Since tests run sequentially by default, this is acceptable. If parallel test execution is ever enabled, consider using t.Cleanup() to restore original option values.

internal/integration/integration_test.go (4)

33-73: Correct cleanup pattern for TestMain.

The implementation properly:

  1. Creates a package-level temp directory
  2. Sets plugin options before any tests run
  3. Captures m.Run() return code
  4. Cleans up the temp directory
  5. Exits with the captured code

This addresses the previous review feedback about defer os.RemoveAll not executing with os.Exit.


76-83: Correct ordering: SetPluginOption before GetPlugin.

Setting plugin options before calling GetPlugin ensures the plugin instance is created with the correct data-dir value. This addresses the previous review feedback about the ordering issue.


262-278: Good approach using yaml.Marshal for config generation.

Building the config as a map structure and marshaling with yaml.Marshal is more reliable than manually crafting YAML strings, avoiding formatting and indentation pitfalls.


97-108: Good use of config constants for plugin identifiers.

Replacing hardcoded strings like "badger" and "sqlite" with config.DefaultBlobPlugin and config.DefaultMetadataPlugin improves maintainability. If default plugin names change, tests will automatically use the updated values.

Also applies to: 191-191, 200-200, 212-215, 232-235, 304-317, 334-334


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.

agaffney
agaffney previously approved these changes Dec 2, 2025
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

Copy link
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: 2

🧹 Nitpick comments (4)
database/plugin/plugin_test.go (1)

12-29: Good initial test coverage; consider adding a few more cases.

The tests cover the core scenarios. Consider adding tests for:

  1. PluginTypeBlob with badger plugin (since it's imported)
  2. Plugin not found error case (e.g., SetPluginOption(PluginTypeMetadata, "nonexistent", ...))
  3. Uint option handling (e.g., badger's block-cache-size)

Also note that this test mutates global plugin state (cmdlineOptions.dataDir). If tests run in parallel, consider resetting the value in a cleanup function.

database/database.go (1)

136-144: Process‑wide side effects from SetPluginOption in New

Wiring DataDir via plugin.SetPluginOption is logically correct and matches the documented semantics (nil config → .dingo, empty string → in‑memory, non‑empty → explicit path). However, SetPluginOption mutates global plugin option state, so each New call updates process‑wide settings for the selected blob/metadata plugins.

If callers ever construct multiple Database instances with different DataDir values in the same process (or concurrently), they’ll be sharing and overwriting these global options. That’s probably fine for the current CLI/config usage, but it’d be good to either (a) document that DataDir is effectively process‑wide and not concurrency‑safe, or (b) in the longer term, move data-dir to per‑instance options passed into blob.New/metadata.New instead of via global plugin state.

internal/integration/integration_test.go (2)

18-18: YAML‑based config generation is cleaner; consider temp paths as a minor follow‑up

Building the config via a map[string]any and yaml.Marshal is a nice improvement over hand‑written YAML, and the checks against config.DefaultBlobPlugin / config.DefaultMetadataPlugin validate the important parts of the loaded config without depending on formatting.

One minor consideration: the hard‑coded /tmp/test-config-badger and /tmp/test-config-sqlite.db paths are a bit Unix‑specific. Since the test never actually instantiates plugins from this config, it’s not a correctness issue today, but if you later reuse this config for real plugin creation, switching those to t.TempDir() or os.TempDir() (and deriving filenames from that) would make the test more portable.

Also applies to: 199-221, 230-230, 242-243, 245-245, 247-248


268-268: Switch to config.DefaultBlobPlugin keeps switching test aligned with config

Using config.DefaultBlobPlugin in findPluginEntry avoids the literal "badger" here and keeps this test consistent with the configured default blob plugin name. The assertion message still mentions “badger”, but that’s only cosmetic and can be adjusted later if the default ever changes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7f83c1 and 13d0a67.

📒 Files selected for processing (7)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • database/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • internal/integration/integration_test.go (10 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
database/plugin/plugin_test.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
database/plugin/register.go (1)
  • PluginTypeMetadata (27-27)
database/plugin/plugin.go (2)
database/plugin/register.go (2)
  • PluginType (24-24)
  • PluginTypeName (31-40)
database/plugin/option.go (4)
  • PluginOptionTypeString (29-29)
  • PluginOptionTypeBool (30-30)
  • PluginOptionTypeInt (31-31)
  • PluginOptionTypeUint (32-32)
database/database.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
database/plugin/register.go (2)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
internal/integration/integration_test.go (3)
database/plugin/register.go (3)
  • GetPlugin (111-120)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
internal/config/config.go (2)
  • DefaultBlobPlugin (50-50)
  • DefaultMetadataPlugin (51-51)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
🪛 LanguageTool
PLUGIN_DEVELOPMENT.md

[style] ~294-~294: ‘prior to’ might be wordy. Consider a shorter alternative.
Context: ...'s destination variable in the registry prior to plugin instantiation. If the requested ...

(EN_WORDINESS_PREMIUM_PRIOR_TO)

⏰ 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). (17)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.25.x, macos-latest)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: nilaway
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: lint
  • GitHub Check: Analyze (go)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: lint
  • GitHub Check: Analyze (go)
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: nilaway
🔇 Additional comments (5)
PLUGIN_DEVELOPMENT.md (1)

281-299: Good documentation for the new programmatic option override feature.

The documentation clearly explains how to use SetPluginOption for tests, includes practical examples, and appropriately notes the non-fatal behavior for undefined options. The recommendation to use t.TempDir() for test isolation is valuable guidance.

database/plugin/metadata/sqlite/plugin.go (1)

34-34: Default data directory now set to ".dingo" - consistent implementation.

The default value is defined in two places: initCmdlineOptions() for the runtime default and DefaultValue for the plugin option metadata. Both are correctly set to .dingo.

Also applies to: 51-51

database/plugin/blob/badger/plugin.go (1)

46-46: Both plugins safely share the ".dingo" directory through distinct storage patterns.

The Badger blob plugin creates a blob subdirectory within the data directory, while SQLite stores its data as metadata.sqlite within the same directory. These non-overlapping storage locations prevent file conflicts or data corruption.

internal/integration/integration_test.go (2)

44-71: Good use of config defaults and per‑test data‑dirs for plugin lifecycle

Switching to config.DefaultBlobPlugin / config.DefaultMetadataPlugin here keeps the tests aligned with the central configuration, and the SetPluginOption(..., "data-dir", t.TempDir()) calls before Start() give each run an isolated on‑disk location. This avoids pollution of the new .dingo default and reduces flakiness from shared state. No issues spotted.


140-178: Lifecycle test updates correctly respect defaults and isolate storage

Using expectedBlobs := []string{config.DefaultBlobPlugin, "gcs", "s3"} and expectedMetadata := []string{config.DefaultMetadataPlugin} keeps this test resilient to future renames of the default plugins. The added SetPluginOption(..., "data-dir", t.TempDir()) calls before GetPlugin/Start for badger/sqlite correctly ensure that these “works with defaults” checks don’t trample the shared .dingo directory. This all looks consistent with the new defaulting behavior.

Copy link
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: 1

🧹 Nitpick comments (3)
PLUGIN_DEVELOPMENT.md (1)

281-299: Good documentation for the new test pattern.

Clear explanation of programmatic option overrides with practical examples. The guidance on using t.TempDir() for test isolation is valuable.

Minor nit: Consider "before" instead of "prior to" on line 294 for conciseness.

database/plugin/plugin_test.go (1)

11-29: Good basic test coverage for SetPluginOption.

The test validates the three key behaviors: successful assignment, type mismatch error, and non-fatal handling of unknown options.

Consider adding test cases for:

  • Plugin not found scenario (returns error)
  • Bool, int, and uint option types
database/plugin/plugin.go (1)

71-151: Thread safety consideration for SetPluginOption.

The function writes directly to opt.Dest (e.g., &cmdlineOptions.dataDir) without acquiring the plugin's cmdlineOptionsMutex. If SetPluginOption runs concurrently with NewFromCmdlineOptions (which reads under RLock), there's a potential data race.

The current usage in database.New() is safe because SetPluginOption completes before plugin instantiation. However, for general-purpose use, consider documenting that SetPluginOption must be called before any plugin instantiation, or explore acquiring the mutex if feasible.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7f83c1 and 13d0a67.

📒 Files selected for processing (7)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • database/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • internal/integration/integration_test.go (10 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
database/database.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
database/plugin/register.go (2)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
database/plugin/plugin_test.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
database/plugin/register.go (1)
  • PluginTypeMetadata (27-27)
internal/integration/integration_test.go (3)
database/plugin/register.go (1)
  • GetPlugin (111-120)
internal/config/config.go (1)
  • DefaultBlobPlugin (50-50)
database/plugin/plugin.go (1)
  • SetPluginOption (71-151)
database/plugin/plugin.go (2)
database/plugin/register.go (2)
  • PluginType (24-24)
  • PluginTypeName (31-40)
database/plugin/option.go (4)
  • PluginOptionTypeString (29-29)
  • PluginOptionTypeBool (30-30)
  • PluginOptionTypeInt (31-31)
  • PluginOptionTypeUint (32-32)
🪛 LanguageTool
PLUGIN_DEVELOPMENT.md

[style] ~294-~294: ‘prior to’ might be wordy. Consider a shorter alternative.
Context: ...'s destination variable in the registry prior to plugin instantiation. If the requested ...

(EN_WORDINESS_PREMIUM_PRIOR_TO)

⏰ 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). (9)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: nilaway
  • GitHub Check: Analyze (go)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: Analyze (go)
🔇 Additional comments (5)
database/plugin/blob/badger/plugin.go (1)

46-46: LGTM! Consistent default data directory initialization.

The default data directory is correctly set to ".dingo" in both initCmdlineOptions() and the DefaultValue for the plugin option, ensuring consistent behavior whether the plugin is initialized programmatically or via command-line options.

Also applies to: 63-63

database/database.go (1)

136-144: Well-designed plugin option configuration.

The SetPluginOption calls correctly configure the data-dir option before plugin instantiation. The approach of always setting the option (even when empty) is sound—empty strings trigger in-memory mode while non-empty paths enable persistence. Error handling for both calls is properly implemented.

database/plugin/metadata/sqlite/plugin.go (1)

34-34: LGTM! Consistent with badger plugin defaults.

The SQLite metadata plugin now defaults to ".dingo" in both initCmdlineOptions() and the DefaultValue, maintaining consistency with the badger blob plugin.

Also applies to: 51-51

internal/integration/integration_test.go (2)

157-178: Correct ordering in TestPluginLifecycleEndToEnd.

Unlike TestPluginSystemIntegration, this test correctly calls SetPluginOption before GetPlugin, ensuring the temp directory is used for plugin instantiation.


199-221: Good improvement: programmatic YAML generation.

Using yaml.Marshal instead of a hardcoded YAML string is more robust and avoids formatting/indentation issues.

@wolf31o2 wolf31o2 force-pushed the fix/default-data-dir branch from 13d0a67 to 62aa4b3 Compare December 3, 2025 14:51
Copy link
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

🧹 Nitpick comments (3)
database/plugin/plugin_test.go (1)

12-55: Good test coverage for SetPluginOption.

The test covers the key scenarios: success cases for various types, type enforcement errors, no-op for unknown options, and error for nonexistent plugins.

Note: As the comment on lines 13-15 acknowledges, this test mutates global state. If parallelism is enabled in the future, consider using t.Cleanup to reset options to their original values after each test to prevent cross-test interference.

internal/integration/integration_test.go (1)

32-56: Consider logging or failing on SetPluginOption errors in TestMain.

Discarding errors with _ = on lines 42-48 and 48-53 could silently hide configuration problems that would cause confusing test failures later. Since this is test setup code, consider either:

  1. Logging the error (if the failure is acceptable for some plugin combinations), or
  2. Using panic to fail fast if setting the data-dir is critical.
-	_ = plugin.SetPluginOption(
+	if err := plugin.SetPluginOption(
 		plugin.PluginTypeBlob,
 		config.DefaultBlobPlugin,
 		"data-dir",
 		tmpDir,
-	)
+	); err != nil {
+		// Log but don't fail - some plugins may not support data-dir
+		fmt.Fprintf(os.Stderr, "warning: failed to set blob data-dir: %v\n", err)
+	}
connmanager/connection_manager.go (1)

55-63: PromRegistry addition is solid; no breaking changes detected, documentation optional

Adding PromRegistry prometheus.Registerer to ConnectionManagerConfig cleanly exposes metric registration control. The nil check at line 85 (if cfg.PromRegistry != nil) correctly gates metric initialization, and promauto.With(c.config.PromRegistry) at line 92 uses it properly.

All existing ConnectionManagerConfig literals in the codebase (node.go, connection_manager_test.go) already use keyed field syntax, so positioning PromRegistry as the first field poses no risk of field mis-assignment.

Optional: Consider adding a doc comment to PromRegistry documenting its semantics (e.g., "nil disables metrics; non-nil enables Prometheus registration via promauto.With") for clarity to future callers, though the current implementation is self-documenting through its nil gate.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13d0a67 and 62aa4b3.

📒 Files selected for processing (14)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • connmanager/connection_manager.go (2 hunks)
  • database/database.go (3 hunks)
  • database/plugin/blob/aws/database.go (1 hunks)
  • database/plugin/blob/badger/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/blob/gcs/plugin_test.go (1 hunks)
  • database/plugin/metadata/sqlite/database.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • database/plugin/register.go (1 hunks)
  • internal/integration/benchmark_test.go (3 hunks)
  • internal/integration/integration_test.go (10 hunks)
✅ Files skipped from review due to trivial changes (1)
  • database/plugin/blob/aws/database.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • database/plugin/blob/badger/plugin.go
  • database/plugin/metadata/sqlite/plugin.go
  • PLUGIN_DEVELOPMENT.md
  • database/database.go
🧰 Additional context used
🧬 Code graph analysis (3)
database/plugin/plugin.go (2)
database/plugin/register.go (2)
  • PluginType (24-24)
  • PluginTypeName (31-40)
database/plugin/option.go (4)
  • PluginOptionTypeString (29-29)
  • PluginOptionTypeBool (30-30)
  • PluginOptionTypeInt (31-31)
  • PluginOptionTypeUint (32-32)
database/plugin/plugin_test.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (2)
  • PluginTypeMetadata (27-27)
  • PluginTypeBlob (28-28)
internal/integration/integration_test.go (3)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (1)
  • GetPlugin (115-124)
internal/config/config.go (2)
  • DefaultBlobPlugin (50-50)
  • DefaultMetadataPlugin (51-51)
⏰ 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). (7)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: go-test (1.25.x, macos-latest)
  • GitHub Check: nilaway
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: Analyze (go)
🔇 Additional comments (16)
database/plugin/blob/gcs/plugin_test.go (1)

28-32: LGTM!

The struct field reordering is a minor stylistic change with no functional impact. The test logic remains correct.

database/plugin/metadata/sqlite/database.go (2)

37-44: LGTM!

Struct field reordering has no functional impact.


162-164: Good security improvement: Tightening directory permissions.

Changing from fs.ModePerm (0777) to 0o755 prevents world-write access to the data directory. This is a sensible default for file-backed storage.

database/plugin/blob/badger/database.go (2)

33-44: LGTM!

The struct field reorganization groups configuration-related fields together, improving readability.


79-81: Consistent permission tightening.

Using 0o755 instead of fs.ModePerm matches the sqlite plugin change, ensuring consistent and secure directory creation across storage backends.

database/plugin/register.go (1)

52-58: LGTM!

The Register function is clean and well-documented. The explicit warning about thread-safety and initialization-only usage is helpful for maintainers.

internal/integration/integration_test.go (3)

59-66: SetPluginOption ordering is correct.

The SetPluginOption calls now properly precede GetPlugin, ensuring the temp directory is configured before plugin instantiation. This addresses the previous review concern.


80-91: Good use of config constants.

Using config.DefaultBlobPlugin and config.DefaultMetadataPlugin instead of hard-coded strings improves maintainability and ensures tests stay in sync with default configuration.


239-300: Well-structured YAML config integration test.

The approach of marshaling a config map to YAML avoids string formatting pitfalls and makes the test configuration more readable and maintainable.

database/plugin/plugin.go (4)

66-77: Thorough documentation of concurrency constraints.

The function comments clearly explain the thread-safety limitations and when this function should be called. This addresses the previous review concern about synchronization.


94-123: Proper nil checks implemented.

The type-checked assignment pattern with explicit nil checks for opt.Dest and the typed destination pointer addresses the previous review concern about potential nil pointer dereferences.


182-216: Good handling of uint64/int conversion.

The PluginOptionTypeUint case properly accepts both uint64 and int values, with a bounds check to reject negative integers. This provides flexibility for callers while maintaining type safety.


224-234: Reasonable fallback behavior for unknown options.

Treating an unknown option as a non-fatal no-op (when the plugin exists) allows callers to set options that may not apply to all plugin implementations without error handling complexity.

internal/integration/benchmark_test.go (1)

100-108: LGTM: explicit backend names wired through cleanly

The added name string field is consistently defined on the backend descriptor struct, initialized for all backends (memory, disk, GCS, S3), and used for sub‑benchmark naming and temp‑dir prefixes. No correctness or maintainability concerns from these changes.

Also applies to: 135-138, 155-158

connmanager/connection_manager.go (2)

37-41: connectionInfo field order change appears safe

connectionInfo is an unexported struct used only inside this package/file, so moving isInbound after peerAddr doesn’t affect external APIs or behavior. No issues from this change.


48-53: Field reordering is safe; no API compatibility risk

All ConnectionManager instantiation in the codebase occurs exclusively through the NewConnectionManager factory function, which uses keyed fields. No unkeyed struct literals exist, and external code only interacts with ConnectionManager via pointers. Reordering fields poses no breaking change to the API.

Likely an incorrect or invalid review comment.

@wolf31o2 wolf31o2 force-pushed the fix/default-data-dir branch from 62aa4b3 to 6d3a638 Compare December 3, 2025 15:29
Copy link
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: 1

🧹 Nitpick comments (3)
database/plugin/plugin.go (1)

94-216: Consider extracting nil-check logic into a helper to reduce repetition.

Each type case repeats the same pattern: check opt.Dest == nil, type-assert, check result nil. While the current implementation is correct and readable, a helper function could reduce boilerplate:

func checkDest[T any](opt PluginOption, optionName string) (*T, error) {
    if opt.Dest == nil {
        return nil, fmt.Errorf("nil destination for option %s", optionName)
    }
    dest, ok := opt.Dest.(*T)
    if !ok || dest == nil {
        return nil, fmt.Errorf("invalid destination type for option %s", optionName)
    }
    return dest, nil
}

However, this is a minor improvement and the current explicit approach is also acceptable.

database/plugin/plugin_test.go (2)

12-55: Test mutates global state without cleanup; consider restoring original values.

The test modifies global plugin options (e.g., data-dir for sqlite and badger) but doesn't restore original values afterward. This could cause test pollution if other tests depend on default values.

Consider capturing and restoring the original values:

 func TestSetPluginOption_SuccessAndTypeCheck(t *testing.T) {
+	// Store original values for cleanup
+	// (would require a GetPluginOption helper or direct field access)
+
 	// Note: This test mutates global plugin state...

Alternatively, run this test in isolation or use t.Cleanup() to restore state.


34-37: Use t.TempDir() instead of hardcoded /tmp/test-badger for portability.

Hardcoded paths can fail on Windows and may cause collisions between test runs.

 	// Test setting data-dir for badger plugin (blob type)
-	if err := plug.SetPluginOption(plug.PluginTypeBlob, "badger", "data-dir", "/tmp/test-badger"); err != nil {
+	if err := plug.SetPluginOption(plug.PluginTypeBlob, "badger", "data-dir", t.TempDir()); err != nil {
 		t.Fatalf("unexpected error setting badger data-dir: %v", err)
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62aa4b3 and 6d3a638.

📒 Files selected for processing (14)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • connmanager/connection_manager.go (2 hunks)
  • database/database.go (3 hunks)
  • database/plugin/blob/aws/database.go (1 hunks)
  • database/plugin/blob/badger/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/blob/gcs/plugin_test.go (1 hunks)
  • database/plugin/metadata/sqlite/database.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • database/plugin/register.go (1 hunks)
  • internal/integration/benchmark_test.go (3 hunks)
  • internal/integration/integration_test.go (10 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • database/plugin/metadata/sqlite/plugin.go
  • PLUGIN_DEVELOPMENT.md
  • database/plugin/register.go
  • database/plugin/metadata/sqlite/database.go
  • database/plugin/blob/badger/plugin.go
  • connmanager/connection_manager.go
  • database/database.go
  • internal/integration/benchmark_test.go
  • database/plugin/blob/aws/database.go
  • database/plugin/blob/badger/database.go
  • database/plugin/blob/gcs/plugin_test.go
🧰 Additional context used
🧬 Code graph analysis (2)
database/plugin/plugin.go (2)
database/plugin/register.go (2)
  • PluginType (24-24)
  • PluginTypeName (31-40)
database/plugin/option.go (4)
  • PluginOptionTypeString (29-29)
  • PluginOptionTypeBool (30-30)
  • PluginOptionTypeInt (31-31)
  • PluginOptionTypeUint (32-32)
internal/integration/integration_test.go (3)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (3)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
  • GetPlugin (115-124)
internal/config/config.go (2)
  • DefaultBlobPlugin (50-50)
  • DefaultMetadataPlugin (51-51)
⏰ 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). (6)
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: nilaway
🔇 Additional comments (4)
database/plugin/plugin.go (1)

66-235: LGTM! The implementation is thorough with proper type safety and nil checks.

The function correctly implements:

  • Type-checked assignments for all supported option types
  • Nil destination validation before dereferencing
  • Safe type assertions with explicit error handling
  • Clear documentation of synchronization requirements

The previous review concerns about nil pointer dereferences have been properly addressed with the two-step validation pattern (checking opt.Dest == nil first, then safe type assertion).

internal/integration/integration_test.go (3)

62-120: LGTM! Plugin options are correctly set before instantiation.

The test now properly calls SetPluginOption before GetPlugin, ensuring plugins use the test-specific temp directories. This addresses the previous review concern about ordering.


171-237: LGTM! Lifecycle test properly configures plugins before instantiation.

The test correctly sets data-dir options before retrieving plugin instances, ensuring isolated test directories.


239-308: LGTM! YAML config test is well-structured.

Using yaml.Marshal to generate the config file avoids potential YAML indentation issues that could occur with raw string literals.

@wolf31o2 wolf31o2 force-pushed the fix/default-data-dir branch from 6d3a638 to 836dfbb Compare December 3, 2025 17:25
Copy link
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

🧹 Nitpick comments (1)
database/plugin/plugin_test.go (1)

11-55: Test coverage looks comprehensive.

The test covers the key scenarios: success, type mismatch, unknown options, and plugin-not-found. The warning about global state mutation is appropriate.

Consider using t.TempDir() instead of the hardcoded /tmp/test-badger path on line 35 for better cross-platform compatibility and automatic cleanup:

-	if err := plug.SetPluginOption(plug.PluginTypeBlob, "badger", "data-dir", "/tmp/test-badger"); err != nil {
+	if err := plug.SetPluginOption(plug.PluginTypeBlob, "badger", "data-dir", t.TempDir()); err != nil {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3a638 and 836dfbb.

📒 Files selected for processing (14)
  • PLUGIN_DEVELOPMENT.md (1 hunks)
  • connmanager/connection_manager.go (2 hunks)
  • database/database.go (3 hunks)
  • database/plugin/blob/aws/database.go (1 hunks)
  • database/plugin/blob/badger/database.go (2 hunks)
  • database/plugin/blob/badger/plugin.go (2 hunks)
  • database/plugin/blob/gcs/plugin_test.go (1 hunks)
  • database/plugin/metadata/sqlite/database.go (2 hunks)
  • database/plugin/metadata/sqlite/plugin.go (2 hunks)
  • database/plugin/plugin.go (1 hunks)
  • database/plugin/plugin_test.go (1 hunks)
  • database/plugin/register.go (1 hunks)
  • internal/integration/benchmark_test.go (3 hunks)
  • internal/integration/integration_test.go (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (11)
  • database/plugin/metadata/sqlite/database.go
  • PLUGIN_DEVELOPMENT.md
  • database/database.go
  • database/plugin/plugin.go
  • database/plugin/blob/badger/database.go
  • connmanager/connection_manager.go
  • database/plugin/metadata/sqlite/plugin.go
  • database/plugin/blob/gcs/plugin_test.go
  • database/plugin/blob/aws/database.go
  • internal/integration/benchmark_test.go
  • database/plugin/blob/badger/plugin.go
🧰 Additional context used
🧬 Code graph analysis (2)
internal/integration/integration_test.go (2)
database/plugin/register.go (3)
  • PluginTypeBlob (28-28)
  • PluginTypeMetadata (27-27)
  • GetPlugin (115-124)
internal/config/config.go (2)
  • DefaultBlobPlugin (50-50)
  • DefaultMetadataPlugin (51-51)
database/plugin/plugin_test.go (2)
database/plugin/plugin.go (1)
  • SetPluginOption (78-235)
database/plugin/register.go (2)
  • PluginTypeMetadata (27-27)
  • PluginTypeBlob (28-28)
⏰ 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). (8)
  • GitHub Check: docker (ubuntu-latest, amd64)
  • GitHub Check: go-test (1.25.x, windows-latest)
  • GitHub Check: go-test (1.24.x, ubuntu-latest)
  • GitHub Check: go-test (1.25.x, macos-latest)
  • GitHub Check: go-test (1.24.x, windows-latest)
  • GitHub Check: go-test (1.24.x, macos-latest)
  • GitHub Check: nilaway
  • GitHub Check: Analyze (go)
🔇 Additional comments (5)
database/plugin/register.go (1)

52-58: LGTM!

The thread-safety documentation is accurate and helpful. The guidance to call Register only during init() functions aligns with the typical plugin registration pattern in Go.

internal/integration/integration_test.go (4)

33-73: TestMain correctly handles cleanup before os.Exit.

The implementation properly addresses the issue where defer wouldn't execute with os.Exit. Capturing the return code, performing cleanup, logging cleanup errors without failing, and then exiting is the correct pattern.


76-108: Correct ordering: SetPluginOption before GetPlugin.

The plugin options are now set before plugin instantiation, ensuring the temp directories are used when NewFromOptionsFunc() is called.


261-283: Good approach: programmatic YAML generation avoids formatting pitfalls.

Using yaml.Marshal with a map structure is more robust than raw YAML strings, avoiding indentation and formatting issues.


208-246: Consistent pattern: data-dir set before plugin instantiation.

The test correctly sets temp directories before calling GetPlugin, ensuring isolated test environments.

Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
@wolf31o2 wolf31o2 force-pushed the fix/default-data-dir branch from 836dfbb to 930411a Compare December 3, 2025 17:42
@wolf31o2 wolf31o2 requested a review from agaffney December 3, 2025 20:39
@wolf31o2 wolf31o2 merged commit 0a2b68c into main Dec 3, 2025
15 of 17 checks passed
@wolf31o2 wolf31o2 deleted the fix/default-data-dir branch December 3, 2025 21:51
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.

3 participants