feat: support merging multiple subscriptions

This commit is contained in:
2026-07-19 23:58:02 +08:00
parent fb4d927220
commit 087869d84f
17 changed files with 1341 additions and 60 deletions

View File

@ -4,6 +4,7 @@ package model
import (
"fmt"
"path/filepath"
"sort"
)
// SubscriptionStatus mirrors Python's SubscriptionStatus(str, Enum).
@ -56,29 +57,40 @@ func NewSubscriptionsData() *SubscriptionsData {
return &SubscriptionsData{Subscriptions: make(map[string]*Subscription)}
}
// GetActiveSubscription returns the currently active subscription, if any.
func (d *SubscriptionsData) GetActiveSubscription() *Subscription {
// GetActiveSubscriptions returns every subscription currently marked active,
// sorted by name for deterministic ordering. Multiple subscriptions may be
// active simultaneously — config apply merges all of them (see
// internal/corecfg), prefixing each proxy's name with its source
// subscription's name to avoid collisions.
func (d *SubscriptionsData) GetActiveSubscriptions() []*Subscription {
var actives []*Subscription
for _, sub := range d.Subscriptions {
if sub.Status == StatusActive {
return sub
actives = append(actives, sub)
}
}
return nil
sort.Slice(actives, func(i, j int) bool { return actives[i].Name < actives[j].Name })
return actives
}
// SetActive marks name as active and deactivates all others. Returns false if
// name does not exist.
// SetActive marks name as active, in addition to any other subscriptions
// already active. Returns false if name does not exist.
func (d *SubscriptionsData) SetActive(name string) bool {
if _, ok := d.Subscriptions[name]; !ok {
sub, ok := d.Subscriptions[name]
if !ok {
return false
}
for subName, sub := range d.Subscriptions {
if subName == name {
sub.Status = StatusActive
} else {
sub.Status = StatusInactive
}
sub.Status = StatusActive
return true
}
// SetInactive marks name as inactive. Returns false if name does not exist.
func (d *SubscriptionsData) SetInactive(name string) bool {
sub, ok := d.Subscriptions[name]
if !ok {
return false
}
sub.Status = StatusInactive
return true
}