refactor: consolidate duplicated tool/prompt logic into entityRegistry#1148
refactor: consolidate duplicated tool/prompt logic into entityRegistry#1148rogueslasher wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughIntroduces ChangesGeneric entityRegistry and MCPManager refactor
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
internal/broker/upstream/registry.go (1)
109-112: 💤 Low valueWasteful
toServercall for removals.
toServerbuilds a full server item (mutates name, allocates meta, creates handler closure) just to extract the prefixed name. Consider adding agetPrefixedName func(E) stringto avoid the allocation overhead on removals.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/broker/upstream/registry.go` around lines 109 - 112, The removal loop in the registry.go file calls `r.toServer(item)` just to extract the prefixed name via `r.getServerName()`, which is wasteful since `toServer` performs full server item construction (name mutation, meta allocation, handler closure creation). Add a new method `getPrefixedName(item E) string` that directly extracts the prefixed name from an item without the overhead of full conversion, then replace the `r.getServerName(r.toServer(item))` call in the removal loop with `r.getPrefixedName(item)` to eliminate unnecessary allocations.internal/broker/upstream/manager_test.go (1)
381-381: ⚡ Quick winConsider adding a test helper for serverItems access.
Tests directly manipulate and read the unexported
serverItemsfield. While legal within the same package, this couples tests to registry internals. AGetServerItemsForTesting()method onentityRegistrywould improve encapsulation and maintainability.Suggested test helper pattern
Add to
entityRegistryinregistry.go:+// GetServerItemsForTesting returns a copy of serverItems for test verification +func (r *entityRegistry[E, S]) GetServerItemsForTesting() []S { + return append([]S(nil), r.serverItems...) +}Then update tests:
-manager.tools.serverItems = make([]server.ServerTool, tc.numServerTools) +manager.tools.SetServerItemsForTesting(make([]server.ServerTool, tc.numServerTools)) -manager.tools.serverItems = []server.ServerTool{{Tool: mcp.Tool{Name: "existing_tool"}}} +manager.tools.SetServerItemsForTesting([]server.ServerTool{{Tool: mcp.Tool{Name: "existing_tool"}}}) -for i, st := range manager.tools.serverItems { +for i, st := range manager.tools.GetServerItemsForTesting() {Also applies to: 758-758, 962-963
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/broker/upstream/manager_test.go` at line 381, Tests directly access the unexported serverItems field on the manager, coupling the tests to internal implementation details. Add a GetServerItemsForTesting() method to the entityRegistry type in registry.go that returns the serverItems field for testing purposes. Then update all three locations where serverItems is accessed in manager_test.go (at line 381, line 758, and lines 962-963) to use this new test helper method instead of directly reading or manipulating the unexported field.internal/broker/upstream/manager.go (1)
400-414: ⚖️ Poor tradeoffRegistry state update could be encapsulated.
Direct manipulation of registry fields (
items,byName,byServedName,serverItems) breaks abstraction. The same pattern repeats for prompts (lines 455-467). Consider adding anapplyDifforupdatemethod toentityRegistrythat handles state transitions internally.This would reduce the duplication between the tools and prompts update blocks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/broker/upstream/manager.go` around lines 400 - 414, The code directly manipulates entityRegistry fields (items, byName, byServedName, serverItems) within the manager's lock/unlock blocks, breaking encapsulation. Add an applyDiff or update method to the entityRegistry type that encapsulates all state transitions internally (recreating byName and byServedName maps, applying deletions with slices.DeleteFunc, and appending new items). Call this new method from the manager code instead of directly manipulating the registry fields. Apply this refactoring to both the tools update block and the prompts update block to eliminate the duplication between them.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/broker/upstream/manager.go`:
- Around line 127-128: The comment for the toolsLock sync.RWMutex contains stale
references to serverTools and serverPrompts which were removed during
refactoring to registry-based fields. Update the comment to accurately reflect
which fields are now actually protected by this lock, removing the outdated
field names and replacing them with the current registry-based field names that
toolsLock guards.
In `@internal/broker/upstream/registry.go`:
- Line 1: The file has Go formatting violations detected by gofmt. Run the `make
fmt` command to automatically reformat the file according to Go style standards.
This will fix all formatting issues in the package upstream file.
- Around line 128-129: The loop iterating over gatewayItems does not validate
that existingPtr is non-nil before dereferencing it when calling
r.getMetaFields(*existingPtr). Add a nil check for existingPtr before
dereferencing it to prevent a panic if listFromGateway() returns map entries
with nil pointer values. Skip processing or handle the case appropriately when
existingPtr is nil within the for loop that iterates over existingName and
existingPtr from gatewayItems.
---
Nitpick comments:
In `@internal/broker/upstream/manager_test.go`:
- Line 381: Tests directly access the unexported serverItems field on the
manager, coupling the tests to internal implementation details. Add a
GetServerItemsForTesting() method to the entityRegistry type in registry.go that
returns the serverItems field for testing purposes. Then update all three
locations where serverItems is accessed in manager_test.go (at line 381, line
758, and lines 962-963) to use this new test helper method instead of directly
reading or manipulating the unexported field.
In `@internal/broker/upstream/manager.go`:
- Around line 400-414: The code directly manipulates entityRegistry fields
(items, byName, byServedName, serverItems) within the manager's lock/unlock
blocks, breaking encapsulation. Add an applyDiff or update method to the
entityRegistry type that encapsulates all state transitions internally
(recreating byName and byServedName maps, applying deletions with
slices.DeleteFunc, and appending new items). Call this new method from the
manager code instead of directly manipulating the registry fields. Apply this
refactoring to both the tools update block and the prompts update block to
eliminate the duplication between them.
In `@internal/broker/upstream/registry.go`:
- Around line 109-112: The removal loop in the registry.go file calls
`r.toServer(item)` just to extract the prefixed name via `r.getServerName()`,
which is wasteful since `toServer` performs full server item construction (name
mutation, meta allocation, handler closure creation). Add a new method
`getPrefixedName(item E) string` that directly extracts the prefixed name from
an item without the overhead of full conversion, then replace the
`r.getServerName(r.toServer(item))` call in the removal loop with
`r.getPrefixedName(item)` to eliminate unnecessary allocations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b004d583-9c82-4347-b1b7-17c97221aee6
📒 Files selected for processing (3)
internal/broker/upstream/manager.gointernal/broker/upstream/manager_test.gointernal/broker/upstream/registry.go
Signed-off-by: rogueslasher <aniketpandey25092005@gmail.com>
1d1240f to
57a83d6
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
Signed-off-by: rogueslasher <aniketpandey25092005@gmail.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@maleck13 please review this one , thank you |
|
@rogueslasher,Read this with my guard up... it's a refactor of the federation state, so all that matters is whether it preserves behaviour. Went looking for a dropped guard and couldn't find one: the generic One small thing: in Nice cleanup... the generics read well. |
Refactors the upstream manager by extracting a generic
entityRegistryto eliminate duplicated tool and prompt management logic. Previously, tools and prompts had separate implementations for several operations despite sharing nearly identical behavior. This change consolidates that logic into a single reusable registry abstraction while preserving the existing public API and behavior.Changes
internal/broker/upstream/registry.gocontaining the new genericentityRegistry.MCPManagerto use separate tool and prompt registries backed by the shared implementation.closes #1103
Summary by CodeRabbit