feat(tmmongo): add WithSettingsCheckInterval for tenant config revalidation (#376)#377
Conversation
…dation (#376) Ports revalidation logic from tmpostgres.Manager to tmmongo.Manager. Periodically checks tenant config and evicts cached connections for suspended/purged tenants. Default interval: 30s. Includes 11 new tests. X-Lerian-Ref: 0x1
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe change adds periodic, per-tenant asynchronous settings revalidation for cached MongoDB connections in the tenant manager. A new option Sequence DiagramsequenceDiagram
participant Caller
participant Manager
participant Cache
participant TMgrAPI as Tenant Manager API
participant Revalidator
Caller->>Manager: GetConnection(tenantID)
Manager->>Cache: Lookup cached connection
alt Cache hit
Manager->>Manager: Ping health check
alt Ping OK
Manager->>Manager: Record LRU timestamp
Manager->>Manager: Check lastSettingsCheck vs interval
alt Revalidation due
Manager->>Manager: Update lastSettingsCheck
Manager->>Revalidator: Spawn revalidatePoolSettings(tenantID)
Manager-->>Caller: Return cached connection
Revalidator->>TMgrAPI: HTTP GET tenant config (with timeout)
alt HTTP 403 (suspended)
Revalidator->>Cache: Evict connection
Revalidator->>Manager: Remove lastAccessed & lastSettingsCheck
else HTTP success
Revalidator->>Manager: ApplyConnectionSettings (no-op for Mongo)
else HTTP error
Revalidator->>Manager: Log warning
end
else Not due
Manager-->>Caller: Return cached connection
end
else Ping failed
Manager-->>Caller: Create new connection
end
else Cache miss
Manager-->>Caller: Create new connection
end
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@commons/tenant-manager/mongo/manager_test.go`:
- Around line 1200-1332: Tests currently bypass Manager.GetConnection by calling
revalidatePoolSettings directly or re-implementing its logic; change the tests
to call manager.GetConnection(ctx, "tenant-...") so the actual cache-hit branch,
mutation of manager.lastSettingsCheck and the goroutine launch are exercised.
Specifically, pre-populate manager.connections["tenant-..."] with a connection
whose DB is non-nil (or a lightweight mock) and set lastAccessed and
lastSettingsCheck so GetConnection returns the cached connection and then
triggers revalidation based on manager.settingsCheckInterval; for the enabled
case set WithSettingsCheckInterval to a small >0 duration and assert the
tenant-manager HTTP callCount increases and lastSettingsCheck was updated, and
for the disabled (zero/negative) cases call GetConnection and assert no HTTP
calls occur and manager.settingsCheckInterval is zero (verify negative is
clamped). Use manager.GetConnection, manager.settingsCheckInterval,
manager.connections, manager.lastSettingsCheck, manager.lastAccessed and avoid
calling manager.revalidatePoolSettings directly.
In `@commons/tenant-manager/mongo/manager.go`:
- Around line 354-360: The eviction path uses context.Background() when
core.IsTenantSuspendedError(err) triggers, which can hang if
Disconnect/CloseConnection blocks; change the call to CloseConnection to use a
bounded context (e.g., create a context with timeout using
settingsRevalidationTimeout via context.WithTimeout) and pass that ctx to
p.CloseConnection (and ensure Disconnect/Close honor ctx), cancel the ctx after
the call so the goroutine cannot block indefinitely; reference
IsTenantSuspendedError, CloseConnection, Disconnect and Close in the change.
- Around line 294-307: The race occurs because shouldRevalidate is computed
under p.mu but p.revalidateWG.Go(...) is called after unlocking, allowing
Close() to clear state before the goroutine is registered; fix by registering
the work while still holding the mutex: move the p.revalidateWG.Go(...) (or at
least a call to revalidateWG.Add/Go-equivalent) so it happens before
p.mu.Unlock(), update p.lastSettingsCheck[tenantID] as currently done, and only
then release p.mu and call p.revalidatePoolSettings(tenantID) from within the
goroutine; reference p.mu, shouldRevalidate, p.revalidateWG.Go,
p.lastSettingsCheck, revalidatePoolSettings, and Close() to locate the code to
change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 44f6a88a-54c5-4be9-bbf2-aa1996106c1f
📒 Files selected for processing (2)
commons/tenant-manager/mongo/manager.gocommons/tenant-manager/mongo/manager_test.go
…tale check, goleak 1. Register revalidation goroutine in WaitGroup before releasing mutex (race fix). 2. Use bounded context for CloseConnection in eviction (prevents hang). 3. Check connection identity before revalidation (stale connection fix). 4. Tests use GetConnection instead of calling revalidatePoolSettings directly. 5. Added goleak verification to detect goroutine leaks. X-Lerian-Ref: 0x1
Summary
Closes #376. Ports the
WithSettingsCheckIntervalrevalidation logic fromtmpostgres.Managertotmmongo.Manager.Changes
WithSettingsCheckInterval(d time.Duration)option added totmmongoTenantSuspendedError→ evicts cached MongoDB connectionClose()waits for in-flight revalidation goroutinesTest plan
go build ./...passesgo test ./commons/tenant-manager/mongo/... -count=1 -short— all pass