-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement v2 interfaces across modules (v1.12.1) #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
66283b2
docs: revise reimplementation plans with gap analysis
intel352 655bd1a
feat: add aggregate health service with providers, caching, and event…
intel352 316def2
feat: add TenantGuard enforcement layer for multi-tenant isolation
intel352 64bb3f6
feat: add dynamic reload manager with orchestrator, circuit breaker, …
intel352 baea918
feat: add contract verifier and performance benchmarks
intel352 6eb0971
feat: add BDD contract tests for reload and health subsystems
intel352 8f84f87
fix: resolve CI lint failures and letsencrypt checksum mismatch
intel352 3867ff2
fix: address all PR review comments
intel352 bbb7e2a
fix: address second round of PR review comments
intel352 80289d2
fix: address remaining PR review comments (round 3)
intel352 d29ee4a
fix: address round 4 PR review comments
intel352 9979492
fix: resolve contextcheck lint error in handleReload
intel352 e42a1d4
fix: address round 5 PR review comments
intel352 e48b208
fix: resolve err113 and wrapcheck lint errors
intel352 1adce01
docs: add modular v2 enhancements design doc
intel352 5a97bac
docs: add modular v2 enhancements implementation plan
intel352 c1477b9
chore: upgrade to Go 1.26, fix plan tech stack reference
intel352 fa3494f
Add WithModuleDependency builder option for config-driven dependency …
intel352 40d2094
feat: add Drainable interface with PreStop drain phase
intel352 ad2b8e5
feat: add application phase tracking with lifecycle transitions
intel352 ff0fc8b
feat: add WithParallelInit for concurrent module initialization
intel352 45ae6aa
feat: add RegisterTypedService/GetTypedService generic helpers
intel352 dd36523
feat: add OnServiceReady callback for service readiness events
intel352 ea32f0c
feat: add Plugin interface with WithPlugins builder option
intel352 d3d44a4
feat: add WithDynamicReload to wire ReloadOrchestrator into app lifec…
intel352 f404d1d
feat: add SecretResolver interface and ExpandSecrets utility
intel352 a7b59a2
feat: add configwatcher module with fsnotify file watching
intel352 1d9270e
feat: add SlogAdapter wrapping *slog.Logger for Logger interface
intel352 107589b
feat: add MetricsProvider interface and CollectAllMetrics
intel352 570c970
fix: address code review findings (C1, C2, I1-I3)
intel352 7a055f0
refactor: modernize codebase with gopls quickfixes
intel352 ef9f676
fix: address Copilot review findings from PR #83
intel352 63fd288
merge: resolve conflicts from origin/main into feat/reimplementation
intel352 357f242
fix: eliminate currentModule race in parallel init
intel352 ae4d98e
ci: upgrade Go version from 1.25 to 1.26 in all workflows
intel352 9b0913f
chore: upgrade Go 1.25 to 1.26 in all sub-module and example go.mod f…
intel352 5450d76
fix: address Go 1.26 lint issues in reverseproxy, scheduler, eventbus
intel352 8ec80f1
fix: resolve core lint issues (gofmt, errcheck, wrapcheck)
intel352 ae21c93
fix: resolve go vet false positives on Debug interface in feeders/yam…
intel352 d0d3f76
fix: correct gofmt formatting and nolint directive syntax
intel352 26568ef
fix: address Copilot review — mutex safety, slice copy, infinite loop…
intel352 c7248f4
fix: add gosec G118 suppression for kinesis and custom_memory eventbus
intel352 393a0e9
fix: pass full dependency graph to computeDepthLevels for accurate pa…
intel352 139711e
fix: reverseproxy proxy copies must preserve Director for backwards c…
intel352 c40ebeb
fix: resolve CI failures in examples, configwatcher, contract check, …
intel352 68985e4
fix: address remaining review comments — races, locking, interfaces, …
intel352 0483c23
fix: unwrap decorators for builder options, validate dependency hints
intel352 9dbf0e0
fix: use wrapped static error for dependency hint validation (err113)
intel352 5dedc9d
feat(eventbus): implement MetricsProvider and Drainable interfaces
intel352 1361527
feat(cache): implement MetricsProvider and Reloadable interfaces
intel352 b15c0aa
feat(scheduler): implement MetricsProvider and Drainable interfaces
intel352 89d13df
feat(database): implement MetricsProvider, Drainable, and Reloadable …
intel352 595d99a
feat(reverseproxy): implement MetricsProvider and Drainable interfaces
intel352 1cfda76
feat(httpserver): implement Drainable, Reloadable, and MetricsProvider
intel352 fdd7c23
chore: bump remaining modules to modular v1.12.1
intel352 23e1ed3
feat(eventlogger): implement Drainable interface
intel352 cce790f
merge: resolve conflicts from origin/main
intel352 5473869
style: fix gofmt formatting in examples and module tests
intel352 8783828
fix: remove replace directives, guard generateUniqueName Elem() panic
intel352 79877c0
fix: address data races and PR review feedback in v2 interfaces
intel352 4400b8c
fix: address CI failures — lint err113, eventlogger buffer overflow
intel352 362b7c4
fix: address PR review round 3 — sync, race, and logic fixes
intel352 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| package cache | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "time" | ||
|
|
||
| "github.com/GoCodeAlone/modular" | ||
| ) | ||
|
|
||
| // Compile-time interface checks. | ||
| var ( | ||
| _ modular.MetricsProvider = (*CacheModule)(nil) | ||
| _ modular.Reloadable = (*CacheModule)(nil) | ||
| ) | ||
|
|
||
| // CollectMetrics implements modular.MetricsProvider. | ||
| // It delegates to the underlying CacheEngine's Stats method. | ||
| // Safe to call before Init (returns empty metrics when engine is nil). | ||
| func (m *CacheModule) CollectMetrics(ctx context.Context) modular.ModuleMetrics { | ||
| if m.cacheEngine == nil { | ||
| return modular.ModuleMetrics{Name: m.name, Values: map[string]float64{}} | ||
| } | ||
| return modular.ModuleMetrics{ | ||
| Name: m.name, | ||
| Values: m.cacheEngine.Stats(ctx), | ||
| } | ||
| } | ||
|
|
||
| // CanReload implements modular.Reloadable. | ||
| func (m *CacheModule) CanReload() bool { | ||
| return true | ||
| } | ||
|
|
||
| // ReloadTimeout implements modular.Reloadable. | ||
| func (m *CacheModule) ReloadTimeout() time.Duration { | ||
| return 5 * time.Second | ||
| } | ||
|
|
||
| // Reload implements modular.Reloadable. | ||
| // It applies configuration changes for DefaultTTL and MaxItems. | ||
| // CleanupInterval is not reloadable since the cleanup ticker is already running. | ||
| // Config writes are protected by configMu (and the engine's mutex for MaxItems) | ||
| // to avoid data races with concurrent reads. | ||
| func (m *CacheModule) Reload(_ context.Context, changes []modular.ConfigChange) error { | ||
| for _, ch := range changes { | ||
| switch ch.FieldPath { | ||
| case "defaultTTL": | ||
| if d, err := time.ParseDuration(ch.NewValue); err == nil { | ||
| m.configMu.Lock() | ||
| m.config.DefaultTTL = d | ||
| m.configMu.Unlock() | ||
| } | ||
| case "maxItems": | ||
| var n int | ||
| if _, err := fmt.Sscan(ch.NewValue, &n); err == nil && n > 0 { | ||
| m.configMu.Lock() | ||
| // MemoryCache reads MaxItems under its own mutex, so lock both. | ||
| if mc, ok := m.cacheEngine.(*MemoryCache); ok { | ||
| mc.mutex.Lock() | ||
| m.config.MaxItems = n | ||
| mc.mutex.Unlock() | ||
| } else { | ||
| m.config.MaxItems = n | ||
| } | ||
| m.configMu.Unlock() | ||
| } | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package cache | ||
|
|
||
| import ( | ||
| "context" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/GoCodeAlone/modular" | ||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| // newTestCacheModule creates a CacheModule initialised with a memory engine for testing. | ||
| func newTestCacheModule(t *testing.T) (*CacheModule, context.Context) { | ||
| t.Helper() | ||
| module := NewModule().(*CacheModule) | ||
| app := newMockApp() | ||
|
|
||
| // Pre-register config with explicit values so struct-tag defaults are not needed. | ||
| cfg := &CacheConfig{ | ||
| Engine: "memory", | ||
| DefaultTTL: 300 * time.Second, | ||
| CleanupInterval: 60 * time.Second, | ||
| MaxItems: 10000, | ||
| } | ||
| app.RegisterConfigSection(module.Name(), modular.NewStdConfigProvider(cfg)) | ||
|
|
||
| require.NoError(t, module.RegisterConfig(app)) // skips (already registered) | ||
| require.NoError(t, module.Init(app)) | ||
|
|
||
| ctx := context.Background() | ||
| require.NoError(t, module.Start(ctx)) | ||
| t.Cleanup(func() { _ = module.Stop(ctx) }) | ||
|
|
||
| return module, ctx | ||
| } | ||
|
|
||
| func TestCacheModule_CollectMetrics(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| module, ctx := newTestCacheModule(t) | ||
|
|
||
| // Add some items | ||
| require.NoError(t, module.Set(ctx, "key1", "val1", time.Minute)) | ||
| require.NoError(t, module.Set(ctx, "key2", "val2", time.Minute)) | ||
| require.NoError(t, module.Set(ctx, "key3", "val3", time.Minute)) | ||
|
|
||
| metrics := module.CollectMetrics(ctx) | ||
| assert.Equal(t, "cache", metrics.Name) | ||
| assert.Equal(t, 3.0, metrics.Values["item_count"]) | ||
| assert.Equal(t, 10000.0, metrics.Values["max_items"]) | ||
| } | ||
|
|
||
| func TestCacheModule_Reloadable(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| module, ctx := newTestCacheModule(t) | ||
|
|
||
| // Verify interface compliance | ||
| var reloadable modular.Reloadable = module | ||
| assert.True(t, reloadable.CanReload()) | ||
| assert.Equal(t, 5*time.Second, reloadable.ReloadTimeout()) | ||
|
|
||
| // Verify reload updates config (cleanupInterval is not reloadable) | ||
| changes := []modular.ConfigChange{ | ||
| {FieldPath: "defaultTTL", NewValue: "600s"}, | ||
| {FieldPath: "maxItems", NewValue: "5000"}, | ||
| } | ||
| require.NoError(t, reloadable.Reload(ctx, changes)) | ||
|
|
||
| assert.Equal(t, 600*time.Second, module.config.DefaultTTL) | ||
| assert.Equal(t, 5000, module.config.MaxItems) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.