优化结构

This commit is contained in:
Yvan
2026-08-29 08:40:15 +08:00
parent b6d25c1a0f
commit 509df03d61
17 changed files with 234 additions and 40 deletions
+47 -9
View File
@@ -16,10 +16,13 @@ import (
const (
ProviderEMQX = platformmq.ProviderEMQX
ProviderKafka = platformmq.ProviderKafka
ProviderRabbitMQ = platformmq.ProviderRabbitMQ
retryTick = time.Second
)
var providers = []string{ProviderEMQX, ProviderKafka, ProviderRabbitMQ}
// Reloadable owns process-wide message clients and the logical subscription
// declarations used to restore them after reconnects or configuration reloads.
type Reloadable struct {
@@ -65,12 +68,11 @@ func New(store *runtimeconfig.Store, logger *slog.Logger) (*Reloadable, func(),
logger: logger,
}
if store != nil {
r.apply(ProviderEMQX, storeConfig(store, ProviderEMQX))
r.apply(ProviderRabbitMQ, storeConfig(store, ProviderRabbitMQ))
r.stop = append(r.stop,
store.Subscribe("mq", ProviderEMQX, func(config runtimeconfig.Config) { r.apply(ProviderEMQX, config) }),
store.Subscribe("mq", ProviderRabbitMQ, func(config runtimeconfig.Config) { r.apply(ProviderRabbitMQ, config) }),
)
for _, provider := range providers {
r.apply(provider, storeConfig(store, provider))
provider := provider
r.stop = append(r.stop, store.Subscribe("mq", provider, func(config runtimeconfig.Config) { r.apply(provider, config) }))
}
}
go r.retryLoop()
cleanup := func() {
@@ -88,7 +90,7 @@ func storeConfig(store *runtimeconfig.Store, provider string) runtimeconfig.Conf
}
// TestConfig creates a short-lived provider client and closes it immediately.
// For RabbitMQ this also checks the configured exchange and queue topology.
// RabbitMQ also checks topology; Kafka reads cluster metadata.
func TestConfig(ctx context.Context, provider string, raw json.RawMessage) error {
if ctx != nil {
select {
@@ -218,6 +220,24 @@ func newProviderClient(provider string, raw json.RawMessage) (platformmq.Client,
ReconnectInterval: configSeconds(values, "reconnect_interval"),
TLS: configBool(values, "tls"),
})
case ProviderKafka:
return platformmq.NewKafka(platformmq.KafkaConfig{
Enabled: true,
Brokers: configStrings(values, "brokers"),
ClientID: configText(values, "client_id"),
GroupID: configText(values, "group_id"),
Username: configText(values, "username"),
Password: configText(values, "password"),
TLS: configBool(values, "tls"),
TLSSkipVerify: configBool(values, "tls_skip_verify"),
StartOffset: configText(values, "start_offset"),
MinBytes: configInt(values, "min_bytes"),
MaxBytes: configInt(values, "max_bytes"),
MaxWait: configSeconds(values, "max_wait"),
ConnectTimeout: configSeconds(values, "connect_timeout"),
ReconnectInterval: configSeconds(values, "reconnect_interval"),
AllowAutoTopicCreation: configBool(values, "allow_auto_topic_creation"),
})
default:
return nil, fmt.Errorf("unsupported message provider %q", provider)
}
@@ -246,6 +266,24 @@ func configInt(values map[string]any, key string) int {
}
}
func configStrings(values map[string]any, key string) []string {
items, ok := values[key].([]any)
if ok {
result := make([]string, 0, len(items))
for _, item := range items {
if value := strings.TrimSpace(fmt.Sprint(item)); value != "" {
result = append(result, value)
}
}
return result
}
stringsValue, ok := values[key].([]string)
if ok {
return append([]string(nil), stringsValue...)
}
return nil
}
func configSeconds(values map[string]any, key string) time.Duration {
seconds := configInt(values, key)
if seconds <= 0 {
@@ -281,7 +319,7 @@ func (r *Reloadable) retryOnce() {
}
r.ensureStateLocked()
now := time.Now()
for _, provider := range []string{ProviderEMQX, ProviderRabbitMQ} {
for _, provider := range providers {
config, exists := r.configs[provider]
if !exists || !config.Enabled {
continue
@@ -631,7 +669,7 @@ func (r *Reloadable) UnsubscribeFrom(ctx context.Context, provider string, topic
func (r *Reloadable) Client(provider string) platformmq.Client {
provider = strings.ToLower(strings.TrimSpace(provider))
if provider != ProviderEMQX && provider != ProviderRabbitMQ {
if provider != ProviderEMQX && provider != ProviderKafka && provider != ProviderRabbitMQ {
return nil
}
return &namedClient{owner: r, provider: provider}