diff --git a/cmd/pkg/cli/start.go b/cmd/pkg/cli/start.go index 04f7b76f..e6343e21 100644 --- a/cmd/pkg/cli/start.go +++ b/cmd/pkg/cli/start.go @@ -92,6 +92,7 @@ func runStartCommand(config StartConfig) func(cmd *cobra.Command, args []string) SecretStore: config.SecretStore, ChartStore: config.ChartStore, }) + defer r.Close() sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) diff --git a/pkg/chart/table.go b/pkg/chart/table.go index 0e4ee715..dbd3939f 100644 --- a/pkg/chart/table.go +++ b/pkg/chart/table.go @@ -101,8 +101,48 @@ func (t *Table) Close() error { t.mu.Lock() defer t.mu.Unlock() - for id := range t.charts { - if _, err := t.free(id); err != nil { + degree := map[*Chart]int{} + for id, chrt := range t.charts { + for _, ports := range t.references[id] { + degree[chrt] += len(ports) + } + } + + var queue []*Chart + for chrt, count := range degree { + if count == 0 { + queue = append(queue, chrt) + } + } + + var charts []*Chart + for len(queue) > 0 { + curr := queue[0] + queue = queue[1:] + + if slices.Contains(charts, curr) { + continue + } + charts = append(charts, curr) + + for _, spec := range curr.GetSpecs() { + id := t.lookup(curr.GetNamespace(), spec.GetKind()) + if next, ok := t.charts[id]; ok { + degree[next]-- + if degree[next] == 0 { + queue = append(queue, next) + } + } + } + } + for chrt, count := range degree { + if count != 0 { + charts = append(charts, chrt) + } + } + + for _, chrt := range charts { + if _, err := t.free(chrt.GetID()); err != nil { return err } } @@ -252,8 +292,8 @@ func (t *Table) linked(chrt *Chart) []*Chart { } } } - for curr, d := range degree { - if d != 0 { + for curr, count := range degree { + if count != 0 { linked = append(linked, curr) } } diff --git a/pkg/symbol/table.go b/pkg/symbol/table.go index 0f544336..5c4c5816 100644 --- a/pkg/symbol/table.go +++ b/pkg/symbol/table.go @@ -93,8 +93,54 @@ func (t *Table) Close() error { t.mu.Lock() defer t.mu.Unlock() - for id := range t.symbols { - if _, err := t.free(id); err != nil { + degree := map[*Symbol]int{} + for id, sb := range t.symbols { + for _, ports := range t.references[id] { + degree[sb] += len(ports) + } + } + + var queue []*Symbol + for sb, count := range degree { + if count == 0 { + queue = append(queue, sb) + } + } + + var symbols []*Symbol + for len(queue) > 0 { + curr := queue[0] + queue = queue[1:] + + if slices.Contains(symbols, curr) { + continue + } + symbols = append(symbols, curr) + + for _, ports := range curr.Ports() { + for _, port := range ports { + id := port.ID + if id == uuid.Nil { + id = t.lookup(curr.Namespace(), port.Name) + } + + if next, ok := t.symbols[id]; ok { + degree[next]-- + if degree[next] == 0 { + queue = append(queue, next) + } + } + } + } + } + for sb, count := range degree { + if count != 0 { + symbols = append(symbols, sb) + } + } + + for _, sb := range symbols { + if _, err := t.free(sb.ID()); err != nil { return err } } @@ -225,13 +271,13 @@ func (t *Table) links(sb *Symbol) { out.Link(in) } - refences := t.references[sb.ID()] - if refences == nil { - refences = make(map[string][]spec.Port) - t.references[sb.ID()] = refences + references := t.references[sb.ID()] + if references == nil { + references = make(map[string][]spec.Port) + t.references[sb.ID()] = references } - refences[port.Port] = append(refences[port.Port], spec.Port{ + references[port.Port] = append(references[port.Port], spec.Port{ ID: ref.ID(), Name: port.Name, Port: name, @@ -334,9 +380,9 @@ func (t *Table) linked(sb *Symbol) []*Symbol { } } } - for curr, d := range degree { - if d != 0 { - linked = append(linked, curr) + for sb, count := range degree { + if count != 0 { + linked = append(linked, sb) } }