Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pkg/console/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ type consoleWebServer struct {
cs consolectx.Context
}

func (c *consoleWebServer) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{
runtime.ResourceManager, // Console needs Manager for resource operations
// Note: No need to list ResourceStore explicitly as Manager already depends on it
}
}

func (c *consoleWebServer) Type() runtime.ComponentType {
return runtime.Console
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/console/counter/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ type ManagerComponent interface {

var _ ManagerComponent = &managerComponent{}

func (c *managerComponent) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{
Comment thread
everfid-ever marked this conversation as resolved.
runtime.ResourceStore,
runtime.EventBus, // Counter depends on EventBus to subscribe to events
}
}

type managerComponent struct {
manager CounterManager
}
Expand Down
178 changes: 104 additions & 74 deletions pkg/core/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ package bootstrap

import (
"context"
"fmt"

"github.com/pkg/errors"

"github.com/apache/dubbo-admin/pkg/common/bizerror"
"github.com/apache/dubbo-admin/pkg/config/app"
"github.com/apache/dubbo-admin/pkg/console/counter"
"github.com/apache/dubbo-admin/pkg/core/logger"
Expand All @@ -34,106 +34,136 @@ func Bootstrap(appCtx context.Context, cfg app.AdminConfig) (runtime.Runtime, er
if err != nil {
return nil, err
}
// 0. initialize event bus
if err := initEventBus(builder); err != nil {
return nil, err
}
// 1. initialize resource store
if err := initResourceStore(cfg, builder); err != nil {
return nil, err
}
// 2. initialize discovery
if err := initializeResourceDiscovery(builder); err != nil {
return nil, err
}
// 3. initialize engine
if err := initializeResourceEngine(builder); err != nil {
return nil, err
}
// 4. initialize resource manager
if err := initResourceManager(builder); err != nil {
return nil, err
}
// 5. initialize console
if err := initializeConsole(builder); err != nil {
return nil, err
}
// 6. initialize counter manager
if err := initializeCounterManager(builder); err != nil {

// Use smart bootstrapper for intelligent component initialization
bootstrapper := NewSmartBootstrapper(builder)

// Initialize all components in dependency order
if err := bootstrapper.bootstrapComponents(appCtx, cfg); err != nil {
return nil, err
}
// 7. initialize diagnostics
if err := initializeDiagnoticsServer(builder); err != nil {
logger.Errorf("got error when init diagnotics server %s", err)
}

// Build and return runtime
rt, err := builder.Build()
if err != nil {
return nil, err
}
return rt, nil
}

func initEventBus(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().EventBus()
if err != nil {
return err
}
return initAndActivateComponent(builder, comp)
// SmartBootstrapper handles intelligent component initialization
type SmartBootstrapper struct {
builder *runtime.Builder
}

func initResourceStore(cfg app.AdminConfig, builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().ResourceStore()
if err != nil {
return errors.Wrapf(err, "could not retrieve resource store %s component", cfg.Store.Type)
// NewSmartBootstrapper creates a new smart bootstrapper
func NewSmartBootstrapper(builder *runtime.Builder) *SmartBootstrapper {
return &SmartBootstrapper{
builder: builder,
}
return initAndActivateComponent(builder, comp)
}
func initResourceManager(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().ResourceManager()

// bootstrapComponents initializes all components in dependency order
func (sb *SmartBootstrapper) bootstrapComponents(
ctx context.Context,
cfg app.AdminConfig,
) error {
logger.Info("Starting smart component bootstrap...")

// Gather all components to initialize
components, err := sb.gatherComponents()
if err != nil {
return err
return bizerror.Wrap(err, bizerror.UnknownError, "failed to gather components")
}
return initAndActivateComponent(builder, comp)
}

func initializeConsole(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().Console()
// Sort components by dependencies
ordered, err := sb.sortComponents(components)
if err != nil {
return err
return bizerror.Wrap(err, bizerror.UnknownError, "failed to sort components by dependencies")
}
return initAndActivateComponent(builder, comp)
}

func initializeResourceDiscovery(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().ResourceDiscovery()
if err != nil {
return err
// Initialize components in order
for i, comp := range ordered {
logger.Infof("[%d/%d] Initializing %s...", i+1, len(ordered), comp.Type())
if err := initAndActivateComponent(sb.builder, comp); err != nil {
return bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to initialize component %s", comp.Type()))
}
logger.Infof("[%d/%d] %s initialized successfully", i+1, len(ordered), comp.Type())
}
return initAndActivateComponent(builder, comp)

logger.Info("All components bootstrapped successfully")
return nil
}

func initializeResourceEngine(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().ResourceEngine()
if err != nil {
return err
// gatherComponents collects all components that need to be initialized
func (sb *SmartBootstrapper) gatherComponents() ([]runtime.Component, error) {
components := []runtime.Component{}

// Core components
coreComps := []struct {
name string
getter func() (runtime.Component, error)
}{
{"EventBus", runtime.ComponentRegistry().EventBus},
{"ResourceStore", runtime.ComponentRegistry().ResourceStore},
{"ResourceDiscovery", runtime.ComponentRegistry().ResourceDiscovery},
{"ResourceEngine", runtime.ComponentRegistry().ResourceEngine},
{"ResourceManager", runtime.ComponentRegistry().ResourceManager},
{"Console", runtime.ComponentRegistry().Console},
}
return initAndActivateComponent(builder, comp)
}

func initializeDiagnoticsServer(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().Get(diagnostics.DiagnosticsServer)
if err != nil {
return err
for _, comp := range coreComps {
c, err := comp.getter()
if err != nil {
return nil, bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to get component %s", comp.name))
}
components = append(components, c)
}

// Optional components
optionalComps := []struct {
name string
typ runtime.ComponentType
}{
{"CounterManager", counter.ComponentType},
{"DiagnosticsServer", diagnostics.DiagnosticsServer},
}
return initAndActivateComponent(builder, comp)

for _, comp := range optionalComps {
c, err := runtime.ComponentRegistry().Get(comp.typ)
if err != nil {
logger.Warnf("Optional component %s not available: %v", comp.name, err)
continue
}
components = append(components, c)
}

return components, nil
}

func initializeCounterManager(builder *runtime.Builder) error {
comp, err := runtime.ComponentRegistry().Get(counter.ComponentType)
// sortComponents sorts components by dependency order
func (sb *SmartBootstrapper) sortComponents(
components []runtime.Component,
) ([]runtime.Component, error) {
// Build dependency graph and perform topological sort
graph := runtime.NewDependencyGraph(components)
sorted, err := graph.TopologicalSort()
if err != nil {
return err
return nil, err
}
return initAndActivateComponent(builder, comp)

// Log initialization order
logger.Info("Component initialization order:")
for i, comp := range sorted {
deps := comp.RequiredDependencies()
if len(deps) > 0 {
logger.Infof(" %d. %s (depends on: %v)", i+1, comp.Type(), deps)
} else {
logger.Infof(" %d. %s (no dependencies)", i+1, comp.Type())
}
}

return sorted, nil
}

func initAndActivateComponent(builder *runtime.Builder, comp runtime.Component) error {
Expand All @@ -143,7 +173,7 @@ func initAndActivateComponent(builder *runtime.Builder, comp runtime.Component)
}
logger.Infof("%s initialized successfully", comp.Type())
if err := builder.ActivateComponent(comp); err != nil {
return errors.Wrapf(err, "failed to activate %s", comp.Type())
return bizerror.Wrap(err, bizerror.UnknownError, fmt.Sprintf("failed to activate %s", comp.Type()))
}
return nil
}
7 changes: 7 additions & 0 deletions pkg/core/discovery/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ type discoveryComponent struct {
subscriptionMgr events.SubscriptionManager
}

func (d *discoveryComponent) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{
runtime.EventBus, // Discovery needs EventBus for event emission
runtime.ResourceStore, // Discovery needs Store for resource storage
}
}

func newDiscoveryComponent() Component {
return &discoveryComponent{
informers: make(map[string]Informers),
Expand Down
8 changes: 8 additions & 0 deletions pkg/core/engine/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func newEngineComponent() Component {
subscribers: make([]events.Subscriber, 0),
}
}

func (e *engineComponent) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{
runtime.EventBus,
runtime.ResourceStore,
}
}

func (e *engineComponent) Type() runtime.ComponentType {
return runtime.ResourceEngine
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/core/events/component.go
Comment thread
everfid-ever marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ type eventBus struct {
subscriberDir map[model.ResourceKind]Subscribers
}

func (b *eventBus) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{} // EventBus has no dependencies
}

func (b *eventBus) Type() runtime.ComponentType {
return runtime.EventBus
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/core/manager/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ type resourceManagerComponent struct {
rm ResourceManager
}

func (r *resourceManagerComponent) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{
runtime.ResourceStore, // Manager needs Store to be initialized first
}
}

func (r *resourceManagerComponent) Type() runtime.ComponentType {
return runtime.ResourceManager
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/core/runtime/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ type Attribute interface {
// Type returns the type of the component
Type() ComponentType
// Order indicates the order of the component during bootstrap, the bigger will be started first
// Deprecated: Use RequiredDependencies() instead for explicit dependency management
Order() int
// RequiredDependencies returns the component types that must be initialized before this component
// The system will ensure all required dependencies are initialized first, or fail with a clear error
// Return an empty slice if the component has no dependencies
RequiredDependencies() []ComponentType
}

// Component defines a process that will be run in the application
Expand Down
Loading
Loading