mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-07 01:28:27 +08:00
fix: Prevent deadlock in runComponent when Prepare fails (#45609)
issue: #45068 When component.Prepare() fails (e.g., net listener creation error), the sign channel was never closed, causing runComponent to block indefinitely at <-sign. This resulted in the entire process hanging after logging the error message. Changes: - Move close(sign) to defer statement in runComponent goroutine - Ensures sign channel is always closed regardless of success/failure - Allows proper error propagation through future.Await() mechanism --------- Signed-off-by: Wei Liu <wei.liu@zilliz.com>
This commit is contained in:
parent
b734de5398
commit
7708abd8fe
@ -114,18 +114,29 @@ func runComponent[T component](ctx context.Context,
|
|||||||
) *conc.Future[component] {
|
) *conc.Future[component] {
|
||||||
sign := make(chan struct{})
|
sign := make(chan struct{})
|
||||||
future := conc.Go(func() (component, error) {
|
future := conc.Go(func() (component, error) {
|
||||||
factory := dependency.NewFactory(localMsg)
|
// Wrap the creation and preparation phase to enable concurrent component startup
|
||||||
var err error
|
prepareFunc := func() (component, error) {
|
||||||
role, err := creator(ctx, factory)
|
defer close(sign)
|
||||||
|
factory := dependency.NewFactory(localMsg)
|
||||||
|
var err error
|
||||||
|
role, err := creator(ctx, factory)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "create component failed")
|
||||||
|
}
|
||||||
|
if err := role.Prepare(); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "prepare component failed")
|
||||||
|
}
|
||||||
|
healthz.Register(role)
|
||||||
|
metricRegister(Registry.GoRegistry)
|
||||||
|
return role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
role, err := prepareFunc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "create component failed")
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := role.Prepare(); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "prepare component failed")
|
// Run() executes after sign is closed, allowing components to start concurrently
|
||||||
}
|
|
||||||
close(sign)
|
|
||||||
healthz.Register(role)
|
|
||||||
metricRegister(Registry.GoRegistry)
|
|
||||||
if err := role.Run(); err != nil {
|
if err := role.Run(); err != nil {
|
||||||
return nil, errors.Wrap(err, "run component failed")
|
return nil, errors.Wrap(err, "run component failed")
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user