From 0ff117da47e4ffec13515b7420d7f56c1f7e99c2 Mon Sep 17 00:00:00 2001 From: ryan Date: Fri, 28 Aug 2026 15:15:26 +0800 Subject: [PATCH] feat(cmd): support dynamic zero-redis pluggable assembly in app bootstrap --- backend/cmd/app.go | 27 ++++++++++++++++++++------ backend/cmd/app_test.go | 42 ++++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/backend/cmd/app.go b/backend/cmd/app.go index 36b19a06..9b761016 100644 --- a/backend/cmd/app.go +++ b/backend/cmd/app.go @@ -27,7 +27,10 @@ import ( "Wavelet/plugins/drivers/driver_asynq_cron" "Wavelet/plugins/drivers/driver_asynq_worker" "Wavelet/plugins/drivers/driver_http" + "Wavelet/plugins/drivers/driver_inproc_cron" + "Wavelet/plugins/drivers/driver_inproc_worker" "Wavelet/plugins/infra/cache" + "Wavelet/plugins/infra/cache_memory" infradb "Wavelet/plugins/infra/database" "Wavelet/plugins/infra/logger" "Wavelet/plugins/infra/storage" @@ -45,12 +48,26 @@ func newWaveletApp(profile core.Profile) *core.App { // 1. Register standard infrastructure plugins app.Use( infradb.New(), - cache.New(), logger.New(), storage.New(), ) - // 2. Register all 8 domain business plugins + // 2. Register Cache and Async/Cron Drivers based on Redis configuration + if config.Config.Redis.Enabled { + app.Use( + cache.New(), + driver_asynq_worker.New(), + driver_asynq_cron.New(), + ) + } else { + app.Use( + cache_memory.New(), + driver_inproc_worker.New(), + driver_inproc_cron.New(), + ) + } + + // 3. Register all 8 domain business plugins app.Use( auth.New(), user.New(), @@ -62,14 +79,12 @@ func newWaveletApp(profile core.Profile) *core.App { system.New(), ) - // 3. Bind Goose migration engine + // 4. Bind Goose migration engine app.SetMigrationEngine(&gooseEngine{}) - // 4. Mount runtime drivers for each aspect + // 5. Mount HTTP runtime driver app.Use( driver_http.New(driver_http.WithAddr(config.Config.App.Addr)), - driver_asynq_worker.New(), - driver_asynq_cron.New(), ) return app diff --git a/backend/cmd/app_test.go b/backend/cmd/app_test.go index f6acfbdd..ed737fa8 100644 --- a/backend/cmd/app_test.go +++ b/backend/cmd/app_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "Wavelet/core" + "Wavelet/pkg/config" ) func TestNewWaveletAppProfiles(t *testing.T) { @@ -26,23 +27,30 @@ func TestNewWaveletAppProfiles(t *testing.T) { require.NotNil(t, app) assert.Equal(t, prof, app.Profile()) - // Verify 4 infra plugins + 8 domain plugins + 3 driver plugins registered + // 3 infra + (1 cache + 2 worker/cron) + 8 domain + 1 http driver = 15 plugins plugins := app.Plugins() assert.Len(t, plugins, 15) - // Verify each standard infra plugin is registered + // Verify standard infra plugins _, ok := app.Plugin("database") assert.True(t, ok, "database plugin missing") - _, ok = app.Plugin("cache") - assert.True(t, ok, "cache plugin missing") - _, ok = app.Plugin("logger") assert.True(t, ok, "logger plugin missing") _, ok = app.Plugin("storage") assert.True(t, ok, "storage plugin missing") + // In zero-Redis mode (default in test) + _, ok = app.Plugin("cache_memory") + assert.True(t, ok, "cache_memory plugin missing") + + _, ok = app.Plugin("driver_inproc_worker") + assert.True(t, ok, "inproc worker driver missing") + + _, ok = app.Plugin("driver_inproc_cron") + assert.True(t, ok, "inproc scheduler driver missing") + // Verify domain plugins _, ok = app.Plugin("auth") assert.True(t, ok, "auth plugin missing") @@ -71,12 +79,24 @@ func TestNewWaveletAppProfiles(t *testing.T) { // Verify driver plugins _, ok = app.Plugin("driver_http") assert.True(t, ok, "http driver missing") - - _, ok = app.Plugin("driver_asynq_worker") - assert.True(t, ok, "worker driver missing") - - _, ok = app.Plugin("driver_asynq_cron") - assert.True(t, ok, "scheduler driver missing") }) } } + +func TestNewWaveletAppWithRedisEnabled(t *testing.T) { + orig := config.Config.Redis.Enabled + config.Config.Redis.Enabled = true + defer func() { config.Config.Redis.Enabled = orig }() + + app := newWaveletApp(core.ProfileAll) + require.NotNil(t, app) + + _, ok := app.Plugin("cache") + assert.True(t, ok, "cache plugin missing in Redis mode") + + _, ok = app.Plugin("driver_asynq_worker") + assert.True(t, ok, "asynq worker driver missing in Redis mode") + + _, ok = app.Plugin("driver_asynq_cron") + assert.True(t, ok, "asynq scheduler driver missing in Redis mode") +}