@@ -19,6 +19,8 @@ package bootstrap
1919
2020import (
2121 "context"
22+ "fmt"
23+ "github.com/duke-git/lancet/v2/slice"
2224
2325 "github.com/pkg/errors"
2426
@@ -34,45 +36,206 @@ func Bootstrap(appCtx context.Context, cfg app.AdminConfig) (runtime.Runtime, er
3436 if err != nil {
3537 return nil , err
3638 }
37- // 0. initialize event bus
38- if err := initEventBus (builder ); err != nil {
39+
40+ // Use smart bootstrapper for intelligent component initialization
41+ bootstrapper := NewSmartBootstrapper (builder )
42+
43+ // Optional: Set bootstrap mode based on configuration
44+ // bootstrapper.SetMode(StrictMode) // Uncomment for strict dependency checking
45+
46+ // Initialize all components in dependency order
47+ if err := bootstrapper .bootstrapComponents (appCtx , cfg ); err != nil {
3948 return nil , err
4049 }
41- // 1. initialize resource store
42- if err := initResourceStore (cfg , builder ); err != nil {
50+
51+ // Build and return runtime
52+ rt , err := builder .Build ()
53+ if err != nil {
4354 return nil , err
4455 }
45- // 2. initialize discovery
46- if err := initializeResourceDiscovery (builder ); err != nil {
47- return nil , err
56+ return rt , nil
57+ }
58+
59+ // BootstrapMode defines how components are initialized
60+ type BootstrapMode int
61+
62+ const (
63+ // CompatibleMode uses dependency declarations when available, falls back to Order()
64+ // This is the default mode for smooth migration
65+ CompatibleMode BootstrapMode = iota
66+
67+ // StrictMode requires all components to declare dependencies, ignores Order()
68+ // Use this mode for new development or after all components are migrated
69+ StrictMode
70+ )
71+
72+ // SmartBootstrapper handles intelligent component initialization
73+ type SmartBootstrapper struct {
74+ builder * runtime.Builder
75+ mode BootstrapMode
76+ }
77+
78+ // NewSmartBootstrapper creates a new smart bootstrapper
79+ func NewSmartBootstrapper (builder * runtime.Builder ) * SmartBootstrapper {
80+ return & SmartBootstrapper {
81+ builder : builder ,
82+ mode : CompatibleMode , // Default to compatible mode
4883 }
49- // 3. initialize engine
50- if err := initializeResourceEngine (builder ); err != nil {
51- return nil , err
84+ }
85+
86+ // SetMode changes the bootstrap mode
87+ func (sb * SmartBootstrapper ) SetMode (mode BootstrapMode ) {
88+ sb .mode = mode
89+ }
90+
91+ // bootstrapComponents initializes all components in dependency order
92+ func (sb * SmartBootstrapper ) bootstrapComponents (
93+ ctx context.Context ,
94+ cfg app.AdminConfig ,
95+ ) error {
96+ logger .Info ("Starting smart component bootstrap..." )
97+
98+ // Gather all components to initialize
99+ components , err := sb .gatherComponents ()
100+ if err != nil {
101+ return errors .Wrap (err , "failed to gather components" )
52102 }
53- // 4. initialize resource manager
54- if err := initResourceManager (builder ); err != nil {
55- return nil , err
103+
104+ // Sort components by dependencies
105+ ordered , err := sb .sortComponents (components )
106+ if err != nil {
107+ return errors .Wrap (err , "failed to sort components by dependencies" )
56108 }
57- // 5. initialize console
58- if err := initializeConsole (builder ); err != nil {
59- return nil , err
109+
110+ // Initialize components in order
111+ for i , comp := range ordered {
112+ logger .Infof ("[%d/%d] Initializing %s..." , i + 1 , len (ordered ), comp .Type ())
113+ if err := initAndActivateComponent (sb .builder , comp ); err != nil {
114+ return errors .Wrapf (err , "failed to initialize component %s" , comp .Type ())
115+ }
116+ logger .Infof ("[%d/%d] %s initialized successfully" , i + 1 , len (ordered ), comp .Type ())
60117 }
61- // 6. initialize counter manager
62- if err := initializeCounterManager (builder ); err != nil {
63- return nil , err
118+
119+ logger .Info ("All components bootstrapped successfully" )
120+ return nil
121+ }
122+
123+ // gatherComponents collects all components that need to be initialized
124+ func (sb * SmartBootstrapper ) gatherComponents () ([]runtime.Component , error ) {
125+ components := []runtime.Component {}
126+
127+ // Core components
128+ coreComps := []struct {
129+ name string
130+ getter func () (runtime.Component , error )
131+ }{
132+ {"EventBus" , runtime .ComponentRegistry ().EventBus },
133+ {"ResourceStore" , runtime .ComponentRegistry ().ResourceStore },
134+ {"ResourceDiscovery" , runtime .ComponentRegistry ().ResourceDiscovery },
135+ {"ResourceEngine" , runtime .ComponentRegistry ().ResourceEngine },
136+ {"ResourceManager" , runtime .ComponentRegistry ().ResourceManager },
137+ {"Console" , runtime .ComponentRegistry ().Console },
64138 }
65- // 7. initialize diagnostics
66- if err := initializeDiagnoticsServer (builder ); err != nil {
67- logger .Errorf ("got error when init diagnotics server %s" , err )
139+
140+ for _ , comp := range coreComps {
141+ c , err := comp .getter ()
142+ if err != nil {
143+ return nil , errors .Wrapf (err , "failed to get component %s" , comp .name )
144+ }
145+ components = append (components , c )
68146 }
69- rt , err := builder .Build ()
147+
148+ // Optional components
149+ optionalComps := []struct {
150+ name string
151+ typ runtime.ComponentType
152+ }{
153+ {"CounterManager" , counter .ComponentType },
154+ {"DiagnosticsServer" , diagnostics .DiagnosticsServer },
155+ }
156+
157+ for _ , comp := range optionalComps {
158+ c , err := runtime .ComponentRegistry ().Get (comp .typ )
159+ if err != nil {
160+ logger .Warnf ("Optional component %s not available: %v" , comp .name , err )
161+ continue
162+ }
163+ components = append (components , c )
164+ }
165+
166+ return components , nil
167+ }
168+
169+ // sortComponents sorts components by dependency order
170+ func (sb * SmartBootstrapper ) sortComponents (
171+ components []runtime.Component ,
172+ ) ([]runtime.Component , error ) {
173+ // Categorize components
174+ withDeps := []runtime.ComponentWithDependencies {}
175+ withoutDeps := []runtime.Component {}
176+
177+ for _ , comp := range components {
178+ if dep , ok := comp .(runtime.ComponentWithDependencies ); ok {
179+ withDeps = append (withDeps , dep )
180+ logger .Debugf ("Component %s declares dependencies: %v" ,
181+ comp .Type (), dep .RequiredDependencies ())
182+ } else {
183+ withoutDeps = append (withoutDeps , comp )
184+ logger .Debugf ("Component %s uses Order() mode: %d" ,
185+ comp .Type (), comp .Order ())
186+ }
187+ }
188+
189+ // If no components declare dependencies, fall back to Order() sorting
190+ if len (withDeps ) == 0 {
191+ logger .Info ("No components declare dependencies, using Order() based initialization" )
192+ return sortByOrder (components ), nil
193+ }
194+
195+ // In strict mode, all components must declare dependencies
196+ if sb .mode == StrictMode && len (withoutDeps ) > 0 {
197+ names := []string {}
198+ for _ , comp := range withoutDeps {
199+ names = append (names , string (comp .Type ()))
200+ }
201+ return nil , fmt .Errorf (
202+ "strict mode enabled but the following components don't declare dependencies: %v\n " +
203+ "Please implement RequiredDependencies() for these components" ,
204+ names ,
205+ )
206+ }
207+
208+ // Build dependency graph and perform topological sort
209+ graph := runtime .NewDependencyGraph (components )
210+ sorted , err := graph .TopologicalSort ()
70211 if err != nil {
71212 return nil , err
72213 }
73- return rt , nil
214+
215+ // Log initialization order
216+ logger .Info ("Component initialization order:" )
217+ for i , comp := range sorted {
218+ logger .Infof (" %d. %s" , i + 1 , comp .Type ())
219+ }
220+
221+ return sorted , nil
74222}
75223
224+ // sortByOrder sorts components by Order() value (legacy mode)
225+ func sortByOrder (components []runtime.Component ) []runtime.Component {
226+ sorted := make ([]runtime.Component , len (components ))
227+ copy (sorted , components )
228+
229+ slice .SortBy (sorted , func (a , b runtime.Component ) bool {
230+ return a .Order () > b .Order ()
231+ })
232+
233+ return sorted
234+ }
235+
236+ // Legacy functions below are kept for reference but no longer used
237+ // They can be removed in a future version after all components are migrated
238+
76239func initEventBus (builder * runtime.Builder ) error {
77240 comp , err := runtime .ComponentRegistry ().EventBus ()
78241 if err != nil {
0 commit comments