feat(core): implement cordis configuration extension and migrate all plugins

This commit is contained in:
ryan
2026-08-29 10:53:53 +08:00
parent b43c429544
commit ed8491addf
74 changed files with 1354 additions and 1145 deletions
+1 -9
View File
@@ -6,7 +6,6 @@ package cmd
import (
"Wavelet/core"
"log"
"github.com/spf13/cobra"
)
@@ -15,13 +14,6 @@ var allCmd = &cobra.Command{
Use: "all",
Short: "以融合模式同时启动 API、Worker 和 Scheduler",
Run: func(_ *cobra.Command, _ []string) {
printStartupBanner(startupState{
mode: "all (API + Worker + Scheduler)",
listensForHTTP: true,
})
app := newWaveletApp(core.ProfileAll)
if err := app.Run(); err != nil {
log.Fatalf("[All] run failed: %v\n", err)
}
runProfileApp(core.ProfileAll, "all (API + Worker + Scheduler)", true)
},
}
+1 -9
View File
@@ -5,7 +5,6 @@ package cmd
import (
"Wavelet/core"
"log"
"github.com/spf13/cobra"
)
@@ -14,13 +13,6 @@ var apiCmd = &cobra.Command{
Use: "api",
Short: "wavelet API",
Run: func(_ *cobra.Command, _ []string) {
printStartupBanner(startupState{
mode: "api",
listensForHTTP: true,
})
app := newWaveletApp(core.ProfileAPI)
if err := app.Run(); err != nil {
log.Fatalf("[API] run failed: %v\n", err)
}
runProfileApp(core.ProfileAPI, "api", true)
},
}
+54 -25
View File
@@ -6,7 +6,6 @@ package cmd
import (
"Wavelet/core"
"Wavelet/core/contracts"
"Wavelet/pkg/config"
"Wavelet/plugins/domain/admin"
"Wavelet/plugins/domain/auth"
"Wavelet/plugins/domain/cap"
@@ -22,6 +21,7 @@ import (
"Wavelet/plugins/drivers/driver_inproc_worker"
"Wavelet/plugins/infra/cache"
"Wavelet/plugins/infra/cache_memory"
"Wavelet/plugins/infra/config"
"Wavelet/plugins/infra/logger"
"Wavelet/plugins/infra/storage"
"context"
@@ -38,14 +38,48 @@ import (
infradb "Wavelet/plugins/infra/database"
)
const (
defaultShutdownTimeout = 15 * time.Second
defaultHTTPAddr = "127.0.0.1:3000"
)
// runProfileApp prepares and runs the application for a given profile.
func runProfileApp(profile core.Profile, mode string, listensForHTTP bool) {
app := newWaveletApp(profile)
if err := app.Prepare(); err != nil {
log.Fatalf("[%s] prepare failed: %v\n", mode, err)
}
state := startupState{
mode: mode,
listensForHTTP: listensForHTTP,
env: app.Context().Config().String("app.env", "production"),
}
if listensForHTTP {
state.addr = app.Context().Config().String("app.addr", defaultHTTPAddr)
}
printStartupBanner(state)
if err := app.Run(); err != nil {
log.Fatalf("[%s] run failed: %v\n", mode, err)
}
}
// newWaveletApp creates a core.App wired with Wavelet platform infrastructure, domain plugins, and profile drivers.
//
//nolint:contextcheck
func newWaveletApp(profile core.Profile) *core.App {
app := core.NewApp(
func newWaveletApp(profile core.Profile, opts ...core.AppOption) *core.App {
src, err := config.NewSource()
if err != nil {
log.Fatalf("[App] load config source failed: %v\n", err)
}
appOpts := []core.AppOption{
core.WithProfile(profile),
core.WithShutdownTimeout(time.Duration(config.Config.App.GracefulShutdownTimeout)*time.Second),
)
core.WithConfigSource(src),
core.WithShutdownTimeout(defaultShutdownTimeout),
}
appOpts = append(appOpts, opts...)
app := core.NewApp(appOpts...)
// 1. Register standard infrastructure plugins
app.Use(
@@ -54,20 +88,15 @@ func newWaveletApp(profile core.Profile) *core.App {
storage.New(),
)
// 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(),
)
}
// 2. Register Cache and Async/Cron Drivers (both gated: cache vs cache_memory, asynq vs inproc)
app.Use(
cache.New(),
cache_memory.New(),
driver_asynq_worker.New(),
driver_inproc_worker.New(),
driver_asynq_cron.New(),
driver_inproc_cron.New(),
)
// 3. Register all 8 domain business plugins (admin first to ensure schema and base config tables exist)
app.Use(
@@ -86,7 +115,7 @@ func newWaveletApp(profile core.Profile) *core.App {
// 5. Mount HTTP runtime driver
app.Use(
driver_http.New(driver_http.WithAddr(config.Config.App.Addr)),
driver_http.New(),
)
return app
@@ -236,7 +265,7 @@ func (e *gooseEngine) Migrate(ctx *core.Context, entries []core.MigrationEntry)
return fmt.Errorf("migration: get underlying DB from GORM: %w", err)
}
dialect := gooseDialect()
dialect := gooseDialect(ctx)
dialectStr := string(dialect)
for _, entry := range entries {
@@ -267,11 +296,11 @@ func (e *gooseEngine) Migrate(ctx *core.Context, entries []core.MigrationEntry)
}
// gooseDialect returns the goose dialect based on the configured database engine.
func gooseDialect() goose.Dialect {
if !config.Config.Database.Enabled {
return goose.DialectSQLite3
func gooseDialect(ctx *core.Context) goose.Dialect {
if ctx != nil && ctx.Config() != nil && ctx.Config().Bool("database.enabled", false) {
return goose.DialectPostgres
}
return goose.DialectPostgres
return goose.DialectSQLite3
}
func findMigrationFS(rootFS fs.FS, dialect goose.Dialect) fs.FS {
+57 -18
View File
@@ -5,7 +5,6 @@ package cmd
import (
"Wavelet/core"
"Wavelet/pkg/config"
"testing"
"github.com/stretchr/testify/assert"
@@ -22,13 +21,22 @@ func TestNewWaveletAppProfiles(t *testing.T) {
for _, prof := range profiles {
t.Run(string(prof), func(t *testing.T) {
app := newWaveletApp(prof)
app := newWaveletApp(prof, core.WithConfigValues(map[string]any{
"app": map[string]any{
"addr": "127.0.0.1:0",
},
"redis": map[string]any{
"enabled": false,
},
}))
require.NotNil(t, app)
assert.Equal(t, prof, app.Profile())
// 3 infra + (1 cache + 2 worker/cron) + 8 domain + 1 http driver = 15 plugins
// 3 infra + 2 cache + 4 worker/cron + 8 domain + 1 http driver = 18 plugins
plugins := app.Plugins()
assert.Len(t, plugins, 15)
assert.Len(t, plugins, 18)
require.NoError(t, app.Reconcile())
// Verify standard infra plugins
_, ok := app.Plugin("database")
@@ -41,14 +49,29 @@ func TestNewWaveletAppProfiles(t *testing.T) {
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")
f, ok := app.Fiber("cache_memory")
assert.True(t, ok, "cache_memory fiber missing")
assert.Equal(t, core.FiberActive, f.State())
_, ok = app.Plugin("driver_inproc_worker")
assert.True(t, ok, "inproc worker driver missing")
f, ok = app.Fiber("cache")
assert.True(t, ok, "cache fiber missing")
assert.Equal(t, core.FiberSkipped, f.State())
_, ok = app.Plugin("driver_inproc_cron")
assert.True(t, ok, "inproc scheduler driver missing")
f, ok = app.Fiber("driver_inproc_worker")
assert.True(t, ok, "inproc worker driver fiber missing")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_asynq_worker")
assert.True(t, ok, "asynq worker driver fiber missing")
assert.Equal(t, core.FiberSkipped, f.State())
f, ok = app.Fiber("driver_inproc_cron")
assert.True(t, ok, "inproc scheduler driver fiber missing")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_asynq_cron")
assert.True(t, ok, "asynq scheduler driver fiber missing")
assert.Equal(t, core.FiberSkipped, f.State())
// Verify domain plugins
_, ok = app.Plugin("auth")
@@ -83,19 +106,35 @@ func TestNewWaveletAppProfiles(t *testing.T) {
}
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)
app := newWaveletApp(core.ProfileAll, core.WithConfigValues(map[string]any{
"redis": map[string]any{
"enabled": true,
},
}))
require.NotNil(t, app)
require.NoError(t, app.Reconcile())
_, ok := app.Plugin("cache")
f, ok := app.Fiber("cache")
assert.True(t, ok, "cache plugin missing in Redis mode")
assert.Equal(t, core.FiberActive, f.State())
_, ok = app.Plugin("driver_asynq_worker")
f, ok = app.Fiber("driver_asynq_worker")
assert.True(t, ok, "asynq worker driver missing in Redis mode")
assert.Equal(t, core.FiberActive, f.State())
_, ok = app.Plugin("driver_asynq_cron")
f, ok = app.Fiber("driver_asynq_cron")
assert.True(t, ok, "asynq scheduler driver missing in Redis mode")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("cache_memory")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State())
f, ok = app.Fiber("driver_inproc_worker")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State())
f, ok = app.Fiber("driver_inproc_cron")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State())
}
+13 -7
View File
@@ -1,23 +1,20 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
// Package cmd provides CLI command entry points.
//
//nolint:unused
package cmd
import (
"Wavelet/pkg/buildinfo"
"Wavelet/pkg/config"
"fmt"
"runtime"
"strings"
)
//nolint:unused // startup banner formatting utilities
type startupState struct {
mode string
listensForHTTP bool
env string
addr string
}
func printStartupBanner(state startupState) {
@@ -25,6 +22,15 @@ func printStartupBanner(state startupState) {
}
func formatStartupBanner(state startupState) string {
env := state.env
if env == "" {
env = "production"
}
addr := state.addr
if addr == "" {
addr = "127.0.0.1:3000"
}
lines := []string{
"",
"__ __ _ _ ",
@@ -34,12 +40,12 @@ func formatStartupBanner(state startupState) string {
" \\_/\\_/ \\__,_| \\_/ \\___|_|\\___|\\__|",
fmt.Sprintf(" Wavelet %s", buildinfo.Version),
"",
fmt.Sprintf(" Environment: %s", config.Config.App.Env),
fmt.Sprintf(" Environment: %s", env),
fmt.Sprintf(" Runtime: %s/%s (%s)", runtime.GOOS, runtime.GOARCH, runtime.Version()),
fmt.Sprintf(" Build time: %s", buildTime()),
}
if state.listensForHTTP {
lines = append(lines, fmt.Sprintf(" Listening: http://%s", config.Config.App.Addr))
lines = append(lines, fmt.Sprintf(" Listening: http://%s", addr))
}
lines = append(lines, fmt.Sprintf(" Mode: %s", state.mode), "")
return strings.Join(lines, "\n")
+2 -7
View File
@@ -5,7 +5,6 @@ package cmd
import (
"Wavelet/pkg/buildinfo"
"Wavelet/pkg/config"
"strings"
"testing"
)
@@ -13,23 +12,19 @@ import (
func TestFormatStartupBanner(t *testing.T) {
previousVersion := buildinfo.Version
previousBuildTime := buildinfo.BuildTime
previousEnv := config.Config.App.Env
previousAddr := config.Config.App.Addr
t.Cleanup(func() {
buildinfo.Version = previousVersion
buildinfo.BuildTime = previousBuildTime
config.Config.App.Env = previousEnv
config.Config.App.Addr = previousAddr
})
buildinfo.Version = "v3.2.1"
buildinfo.BuildTime = "2026-07-13T08:00:00Z"
config.Config.App.Env = "production"
config.Config.App.Addr = ":3000"
banner := formatStartupBanner(startupState{
mode: "API",
listensForHTTP: true,
env: "production",
addr: ":3000",
})
for _, want := range []string{
+78 -37
View File
@@ -7,49 +7,56 @@ import (
"Wavelet/core"
"Wavelet/core/contracts"
"Wavelet/core/extpoints"
"Wavelet/pkg/config"
"Wavelet/pkg/idgen"
"context"
"fmt"
"sync/atomic"
"testing"
"time"
"github.com/alicebob/miniredis/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRedisPluggability_Simulation(t *testing.T) {
origRedisEnabled := config.Config.Redis.Enabled
origAddr := config.Config.App.Addr
config.Config.App.Addr = "127.0.0.1:0"
defer func() {
config.Config.Redis.Enabled = origRedisEnabled
config.Config.App.Addr = origAddr
}()
_ = idgen.Init(1)
// ══════════════════════════════════════════════════════════════════════════
// 场景 1: 拔出 Redis (Zero-Redis Monolith 模式)
// ══════════════════════════════════════════════════════════════════════════
t.Run("Scenario_Unplugged_ZeroRedis_Mode", func(t *testing.T) {
config.Config.Redis.Enabled = false
app := newWaveletApp(core.ProfileAll)
app := newWaveletApp(core.ProfileAll, core.WithConfigValues(map[string]any{
"app": map[string]any{
"addr": "127.0.0.1:0",
},
"redis": map[string]any{
"enabled": false,
},
}))
require.NotNil(t, app)
require.NoError(t, app.Reconcile())
// 1. 验证插件挂载形态
_, ok := app.Plugin("cache_memory")
f, ok := app.Fiber("cache_memory")
assert.True(t, ok, "cache_memory 必须挂载")
_, ok = app.Plugin("driver_inproc_worker")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_inproc_worker")
assert.True(t, ok, "driver_inproc_worker 必须挂载")
_, ok = app.Plugin("driver_inproc_cron")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_inproc_cron")
assert.True(t, ok, "driver_inproc_cron 必须挂载")
assert.Equal(t, core.FiberActive, f.State())
_, ok = app.Plugin("cache")
assert.False(t, ok, "分布式 cache 不得挂载")
_, ok = app.Plugin("driver_asynq_worker")
assert.False(t, ok, "asynq_worker 不得挂载")
_, ok = app.Plugin("driver_asynq_cron")
assert.False(t, ok, "asynq_cron 不得挂载")
f, ok = app.Fiber("cache")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "分布式 cache 不得挂载")
f, ok = app.Fiber("driver_asynq_worker")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "asynq_worker 不得挂载")
f, ok = app.Fiber("driver_asynq_cron")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "asynq_cron 不得挂载")
// 2. 注册测试任务与 Cron 定时
var taskExecuted atomic.Int32
@@ -114,25 +121,42 @@ func TestRedisPluggability_Simulation(t *testing.T) {
// 场景 2: 插入 Redis (Distributed Cluster 模式)
// ══════════════════════════════════════════════════════════════════════════
t.Run("Scenario_Plugged_Redis_Mode", func(t *testing.T) {
config.Config.Redis.Enabled = true
mr, err := miniredis.Run()
require.NoError(t, err)
defer mr.Close()
app := newWaveletApp(core.ProfileAll)
app := newWaveletApp(core.ProfileAll, core.WithConfigValues(map[string]any{
"app": map[string]any{
"addr": "127.0.0.1:0",
},
"redis": map[string]any{
"enabled": true,
"addrs": []string{mr.Addr()},
},
}))
require.NotNil(t, app)
require.NoError(t, app.Reconcile())
// 1. 验证插件挂载形态
_, ok := app.Plugin("cache")
f, ok := app.Fiber("cache")
assert.True(t, ok, "分布式 cache 必须挂载")
_, ok = app.Plugin("driver_asynq_worker")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_asynq_worker")
assert.True(t, ok, "driver_asynq_worker 必须挂载")
_, ok = app.Plugin("driver_asynq_cron")
assert.Equal(t, core.FiberActive, f.State())
f, ok = app.Fiber("driver_asynq_cron")
assert.True(t, ok, "driver_asynq_cron 必须挂载")
assert.Equal(t, core.FiberActive, f.State())
_, ok = app.Plugin("cache_memory")
assert.False(t, ok, "纯内存 cache 不得挂载")
_, ok = app.Plugin("driver_inproc_worker")
assert.False(t, ok, "inproc_worker 不得挂载")
_, ok = app.Plugin("driver_inproc_cron")
assert.False(t, ok, "inproc_cron 不得挂载")
f, ok = app.Fiber("cache_memory")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "纯内存 cache 不得挂载")
f, ok = app.Fiber("driver_inproc_worker")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "inproc_worker 不得挂载")
f, ok = app.Fiber("driver_inproc_cron")
assert.True(t, ok)
assert.Equal(t, core.FiberSkipped, f.State(), "inproc_cron 不得挂载")
// 2. 注册测试任务
var asynqTaskExecuted atomic.Int32
@@ -143,7 +167,7 @@ func TestRedisPluggability_Simulation(t *testing.T) {
return nil
}, extpoints.WithTaskTimeout(3*time.Second))
// 3. 启动应用 (连接真实运行中的 Redis 6379)
// 3. 启动应用
bootCtx, bootCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer bootCancel()
require.NoError(t, app.Start(bootCtx))
@@ -172,7 +196,7 @@ func TestRedisPluggability_Simulation(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, taskSvc)
taskID, err := taskSvc.Dispatch(reqCtx, "test:asynq_task", []byte("payload_plugged"), "unit_test")
taskID, err := taskSvc.Dispatch(reqCtx, "test:asynq_task", []byte("payload_plugged"), "default")
require.NoError(t, err)
assert.NotEmpty(t, taskID)
@@ -190,10 +214,20 @@ func TestRedisPluggability_Simulation(t *testing.T) {
// 场景 3: 往复插拔连续切换 (拔出 → 插入 → 再拔出,验证时空可组合性与零残留)
// ══════════════════════════════════════════════════════════════════════════
t.Run("Scenario_Dynamic_Plug_Unplug_Sequence", func(t *testing.T) {
mr, err := miniredis.Run()
require.NoError(t, err)
defer mr.Close()
for i := 1; i <= 2; i++ {
// 1. 拔出 Redis 运行
config.Config.Redis.Enabled = false
appUnplugged := newWaveletApp(core.ProfileAll)
appUnplugged := newWaveletApp(core.ProfileAll, core.WithConfigValues(map[string]any{
"app": map[string]any{
"addr": "127.0.0.1:0",
},
"redis": map[string]any{
"enabled": false,
},
}))
require.NoError(t, appUnplugged.Start(context.Background()))
cacheSvc1, err := core.Inject[contracts.CacheService](appUnplugged.Context())
@@ -203,8 +237,15 @@ func TestRedisPluggability_Simulation(t *testing.T) {
require.NoError(t, appUnplugged.Stop(context.Background()))
// 2. 插入 Redis 运行
config.Config.Redis.Enabled = true
appPlugged := newWaveletApp(core.ProfileAll)
appPlugged := newWaveletApp(core.ProfileAll, core.WithConfigValues(map[string]any{
"app": map[string]any{
"addr": "127.0.0.1:0",
},
"redis": map[string]any{
"enabled": true,
"addrs": []string{mr.Addr()},
},
}))
require.NoError(t, appPlugged.Start(context.Background()))
cacheSvc2, err := core.Inject[contracts.CacheService](appPlugged.Context())
+54 -12
View File
@@ -4,10 +4,12 @@
package cmd
import (
"Wavelet/core/extpoints"
"Wavelet/pkg/buildinfo"
"Wavelet/pkg/config"
"Wavelet/pkg/idgen"
"Wavelet/pkg/logger"
"Wavelet/pkg/trace"
"Wavelet/plugins/infra/config"
"context"
"log"
"time"
@@ -17,23 +19,63 @@ import (
const traceShutdownTimeout = 10 * time.Second
type hostConfig struct {
App struct {
AppName string `config:"app_name" env:"APP_NAME" default:"Wavelet"`
Env string `config:"env" env:"APP_ENV" default:"production"`
NodeID int64 `config:"node_id" env:"APP_NODE_ID" default:"1"`
Addr string `config:"addr" env:"APP_ADDR" default:"127.0.0.1:3000"`
} `config:"app"`
Log struct {
Level string `config:"level" env:"LOG_LEVEL" default:"info"`
Format string `config:"format" env:"LOG_FORMAT" default:"json"`
Output string `config:"output" env:"LOG_OUTPUT" default:"stdout"`
FilePath string `config:"file_path" env:"LOG_FILE_PATH" default:"./logs/app.log"`
MaxSize int `config:"max_size" env:"LOG_MAX_SIZE" default:"100"`
MaxAge int `config:"max_age" env:"LOG_MAX_AGE" default:"30"`
MaxBackups int `config:"max_backups" env:"LOG_MAX_BACKUPS" default:"10"`
Compress bool `config:"compress" env:"LOG_COMPRESS" default:"true"`
} `config:"log"`
OTel struct {
SamplingRate float64 `config:"sampling_rate" env:"OTEL_SAMPLING_RATE" default:"1.0"`
TracerName string `config:"tracer_name" env:"OTEL_TRACER_NAME" default:"github.com/Rain-kl/Wavelet"`
} `config:"otel"`
}
var rootCmd = &cobra.Command{
Use: "wavelet",
PersistentPreRun: func(_ *cobra.Command, _ []string) {
src, err := config.NewSource()
if err != nil {
log.Fatalf("[CMD] load config source failed: %v", err)
}
var cfg hostConfig
reg := extpoints.NewConfigRegistry(src)
_ = reg.Declare("host", extpoints.ConfigBinding{Target: &cfg})
if err := reg.Resolve(); err != nil {
log.Fatalf("[CMD] resolve host config failed: %v", err)
}
_ = reg.Bind("", &cfg)
// Initialize idgen snowflake generator
if err := idgen.Init(cfg.App.NodeID); err != nil {
log.Fatalf("[CMD] init idgen failed: %v", err)
}
logger.Init(logger.Config{
Level: config.Config.Log.Level,
Format: config.Config.Log.Format,
Output: config.Config.Log.Output,
FilePath: config.Config.Log.FilePath,
MaxSize: config.Config.Log.MaxSize,
MaxAge: config.Config.Log.MaxAge,
MaxBackups: config.Config.Log.MaxBackups,
Compress: config.Config.Log.Compress,
Level: cfg.Log.Level,
Format: cfg.Log.Format,
Output: cfg.Log.Output,
FilePath: cfg.Log.FilePath,
MaxSize: cfg.Log.MaxSize,
MaxAge: cfg.Log.MaxAge,
MaxBackups: cfg.Log.MaxBackups,
Compress: cfg.Log.Compress,
})
trace.Init(trace.Config{
AppName: config.Config.App.AppName,
SamplingRate: config.Config.Otel.SamplingRate,
TracerName: config.Config.Otel.TracerName,
AppName: cfg.App.AppName,
SamplingRate: cfg.OTel.SamplingRate,
TracerName: cfg.OTel.TracerName,
})
},
PersistentPostRun: func(_ *cobra.Command, _ []string) {
+1 -9
View File
@@ -5,7 +5,6 @@ package cmd
import (
"Wavelet/core"
"log"
"github.com/spf13/cobra"
)
@@ -14,13 +13,6 @@ var schedulerCmd = &cobra.Command{
Use: "scheduler",
Short: "wavelet Scheduler",
Run: func(_ *cobra.Command, _ []string) {
printStartupBanner(startupState{
mode: "scheduler",
listensForHTTP: false,
})
app := newWaveletApp(core.ProfileSchedule)
if err := app.Run(); err != nil {
log.Fatalf("[Scheduler] run failed: %v\n", err)
}
runProfileApp(core.ProfileSchedule, "scheduler", false)
},
}
+1 -9
View File
@@ -5,7 +5,6 @@ package cmd
import (
"Wavelet/core"
"log"
"github.com/spf13/cobra"
)
@@ -14,13 +13,6 @@ var workerCmd = &cobra.Command{
Use: "worker",
Short: "wavelet Worker",
Run: func(_ *cobra.Command, _ []string) {
printStartupBanner(startupState{
mode: "worker",
listensForHTTP: false,
})
app := newWaveletApp(core.ProfileWorker)
if err := app.Run(); err != nil {
log.Fatalf("[Worker] run failed: %v\n", err)
}
runProfileApp(core.ProfileWorker, "worker", false)
},
}