fix: prepare native cluster deployment
This commit is contained in:
@@ -38,8 +38,10 @@ type cacheInvalidatePayload struct {
|
||||
Ranges []types.Range `json:"ranges"`
|
||||
}
|
||||
|
||||
var kafkaCacheInvalidateConsumerGroup string
|
||||
|
||||
func startKafkaCacheInvalidateConsumer() {
|
||||
startKafkaConsumer("cache_invalidate", handleKafkaCacheInvalidateEvent)
|
||||
kafkaCacheInvalidateConsumerGroup = startKafkaBroadcastConsumer("cache_invalidate", handleKafkaCacheInvalidateEvent)
|
||||
}
|
||||
|
||||
func handleKafkaCacheInvalidateEvent(ctx context.Context, envelope kafkaEnvelope, _ kafka.Message) error {
|
||||
@@ -50,17 +52,18 @@ func handleKafkaCacheInvalidateEvent(ctx context.Context, envelope kafkaEnvelope
|
||||
if tenantID.IsZero() {
|
||||
tenantID = types.TenantID(1)
|
||||
}
|
||||
consume, claimed, err := beginKafkaConsumeForTopic(tenantID, envelope, "cache_invalidate")
|
||||
consumerGroup := kafkaCacheInvalidateConsumerGroup
|
||||
consume, claimed, err := beginKafkaConsumeForTopicWithGroup(tenantID, envelope, "cache_invalidate", consumerGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !claimed {
|
||||
logs.Info.Printf("kafka cache invalidate skipped: event=%s group=%s status=%s", envelope.EventID, kafkaBus.config.ConsumerGroup, consume.Status)
|
||||
logs.Info.Printf("kafka cache invalidate skipped: event=%s group=%s status=%s", envelope.EventID, consumerGroup, consume.Status)
|
||||
return nil
|
||||
}
|
||||
if err = executeKafkaCacheInvalidateEvent(envelope); err != nil {
|
||||
reason := kafkaCommandErrorReason(err)
|
||||
failed, markErr := store.HTTPInfrastructure.MarkKafkaConsumeFailed(tenantID, envelope.EventID, kafkaBus.config.ConsumerGroup, reason, err.Error(), time.Now().UTC().Round(time.Millisecond))
|
||||
failed, markErr := store.HTTPInfrastructure.MarkKafkaConsumeFailed(tenantID, envelope.EventID, consumerGroup, reason, err.Error(), time.Now().UTC().Round(time.Millisecond))
|
||||
if markErr != nil {
|
||||
return markErr
|
||||
}
|
||||
@@ -70,7 +73,7 @@ func handleKafkaCacheInvalidateEvent(ctx context.Context, envelope kafkaEnvelope
|
||||
sleepKafkaRetryBackoff(failed.RetryCount)
|
||||
return err
|
||||
}
|
||||
return store.HTTPInfrastructure.MarkKafkaConsumeSucceeded(tenantID, envelope.EventID, kafkaBus.config.ConsumerGroup, time.Now().UTC().Round(time.Millisecond))
|
||||
return store.HTTPInfrastructure.MarkKafkaConsumeSucceeded(tenantID, envelope.EventID, consumerGroup, time.Now().UTC().Round(time.Millisecond))
|
||||
}
|
||||
|
||||
func executeKafkaCacheInvalidateEvent(envelope kafkaEnvelope) error {
|
||||
|
||||
@@ -34,8 +34,10 @@ type configEventPayload struct {
|
||||
Keys []string `json:"keys"`
|
||||
}
|
||||
|
||||
var kafkaConfigEventConsumerGroup string
|
||||
|
||||
func startKafkaConfigEventConsumer() {
|
||||
startKafkaConsumer("config_event", handleKafkaConfigEvent)
|
||||
kafkaConfigEventConsumerGroup = startKafkaBroadcastConsumer("config_event", handleKafkaConfigEvent)
|
||||
}
|
||||
|
||||
func handleKafkaConfigEvent(ctx context.Context, envelope kafkaEnvelope, _ kafka.Message) error {
|
||||
@@ -46,17 +48,18 @@ func handleKafkaConfigEvent(ctx context.Context, envelope kafkaEnvelope, _ kafka
|
||||
if tenantID.IsZero() {
|
||||
tenantID = types.TenantID(1)
|
||||
}
|
||||
consume, claimed, err := beginKafkaConsumeForTopic(tenantID, envelope, "config_event")
|
||||
consumerGroup := kafkaConfigEventConsumerGroup
|
||||
consume, claimed, err := beginKafkaConsumeForTopicWithGroup(tenantID, envelope, "config_event", consumerGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !claimed {
|
||||
logs.Info.Printf("kafka config event skipped: event=%s group=%s status=%s", envelope.EventID, kafkaBus.config.ConsumerGroup, consume.Status)
|
||||
logs.Info.Printf("kafka config event skipped: event=%s group=%s status=%s", envelope.EventID, consumerGroup, consume.Status)
|
||||
return nil
|
||||
}
|
||||
if err = executeKafkaConfigEvent(envelope); err != nil {
|
||||
reason := kafkaCommandErrorReason(err)
|
||||
failed, markErr := store.HTTPInfrastructure.MarkKafkaConsumeFailed(tenantID, envelope.EventID, kafkaBus.config.ConsumerGroup, reason, err.Error(), time.Now().UTC().Round(time.Millisecond))
|
||||
failed, markErr := store.HTTPInfrastructure.MarkKafkaConsumeFailed(tenantID, envelope.EventID, consumerGroup, reason, err.Error(), time.Now().UTC().Round(time.Millisecond))
|
||||
if markErr != nil {
|
||||
return markErr
|
||||
}
|
||||
@@ -66,7 +69,7 @@ func handleKafkaConfigEvent(ctx context.Context, envelope kafkaEnvelope, _ kafka
|
||||
sleepKafkaRetryBackoff(failed.RetryCount)
|
||||
return err
|
||||
}
|
||||
return store.HTTPInfrastructure.MarkKafkaConsumeSucceeded(tenantID, envelope.EventID, kafkaBus.config.ConsumerGroup, time.Now().UTC().Round(time.Millisecond))
|
||||
return store.HTTPInfrastructure.MarkKafkaConsumeSucceeded(tenantID, envelope.EventID, consumerGroup, time.Now().UTC().Round(time.Millisecond))
|
||||
}
|
||||
|
||||
func executeKafkaConfigEvent(envelope kafkaEnvelope) error {
|
||||
@@ -141,10 +144,20 @@ func beginKafkaConsumeForTopic(tenantID types.TenantID, envelope kafkaEnvelope,
|
||||
if kafkaBus == nil {
|
||||
return nil, false, types.ErrUnsupported
|
||||
}
|
||||
return beginKafkaConsumeForTopicWithGroup(tenantID, envelope, topicName, kafkaBus.config.ConsumerGroup)
|
||||
}
|
||||
|
||||
func beginKafkaConsumeForTopicWithGroup(tenantID types.TenantID, envelope kafkaEnvelope, topicName, consumerGroup string) (*types.KafkaConsumeRecord, bool, error) {
|
||||
if kafkaBus == nil {
|
||||
return nil, false, types.ErrUnsupported
|
||||
}
|
||||
if consumerGroup = strings.TrimSpace(consumerGroup); consumerGroup == "" {
|
||||
consumerGroup = kafkaBus.config.ConsumerGroup
|
||||
}
|
||||
deadline := time.Now().UTC().Add(5 * time.Minute).Round(time.Millisecond)
|
||||
return store.HTTPInfrastructure.BeginKafkaConsume(tenantID, &types.KafkaConsumeRecord{
|
||||
EventID: envelope.EventID,
|
||||
ConsumerGroup: kafkaBus.config.ConsumerGroup,
|
||||
ConsumerGroup: consumerGroup,
|
||||
SourceTopic: kafkaTopic(topicName),
|
||||
EventType: envelope.EventType,
|
||||
BizType: envelope.BizType,
|
||||
|
||||
+37
-2
@@ -5,6 +5,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -88,6 +89,8 @@ type kafkaRuntime struct {
|
||||
|
||||
var kafkaBus *kafkaRuntime
|
||||
|
||||
var kafkaConsumerGroupUnsafeChars = regexp.MustCompile(`[^A-Za-z0-9._-]+`)
|
||||
|
||||
func initKafkaRuntime(raw json.RawMessage) error {
|
||||
if len(raw) == 0 {
|
||||
kafkaBus = nil
|
||||
@@ -272,6 +275,19 @@ func publishKafkaEnvelope(ctx context.Context, topicName string, key string, env
|
||||
type kafkaMessageHandler func(context.Context, kafkaEnvelope, kafka.Message) error
|
||||
|
||||
func startKafkaConsumer(topicName string, handler kafkaMessageHandler) {
|
||||
startKafkaConsumerWithGroup(topicName, "", handler)
|
||||
}
|
||||
|
||||
func startKafkaBroadcastConsumer(topicName string, handler kafkaMessageHandler) string {
|
||||
if kafkaBus == nil || handler == nil {
|
||||
return ""
|
||||
}
|
||||
groupID := kafkaBroadcastConsumerGroup(topicName)
|
||||
startKafkaConsumerWithGroup(topicName, groupID, handler)
|
||||
return groupID
|
||||
}
|
||||
|
||||
func startKafkaConsumerWithGroup(topicName, groupID string, handler kafkaMessageHandler) {
|
||||
if kafkaBus == nil || handler == nil {
|
||||
return
|
||||
}
|
||||
@@ -279,8 +295,11 @@ func startKafkaConsumer(topicName string, handler kafkaMessageHandler) {
|
||||
if topic == "" {
|
||||
topic = topicName
|
||||
}
|
||||
groupID := kafkaBus.config.ConsumerGroup
|
||||
if topicName != "" {
|
||||
groupOverride := groupID != ""
|
||||
if groupID == "" {
|
||||
groupID = kafkaBus.config.ConsumerGroup
|
||||
}
|
||||
if topicName != "" && !groupOverride {
|
||||
groupID += "." + topicName
|
||||
}
|
||||
reader := kafka.NewReader(kafka.ReaderConfig{
|
||||
@@ -324,6 +343,22 @@ func startKafkaConsumer(topicName string, handler kafkaMessageHandler) {
|
||||
logs.Info.Printf("Kafka consumer started: topic=%s group=%s", topic, groupID)
|
||||
}
|
||||
|
||||
func kafkaBroadcastConsumerGroup(topicName string) string {
|
||||
if kafkaBus == nil {
|
||||
return ""
|
||||
}
|
||||
base := strings.TrimSpace(kafkaBus.config.ConsumerGroup)
|
||||
if base == "" {
|
||||
base = "im-server"
|
||||
}
|
||||
nodeID := strings.TrimSpace(currentNodeID())
|
||||
if nodeID == "" {
|
||||
nodeID = "local"
|
||||
}
|
||||
nodeID = kafkaConsumerGroupUnsafeChars.ReplaceAllString(nodeID, "-")
|
||||
return base + "." + topicName + "." + nodeID
|
||||
}
|
||||
|
||||
func (rt *kafkaRuntime) dialer() *kafka.Dialer {
|
||||
dialer := &kafka.Dialer{
|
||||
ClientID: rt.config.ClientID,
|
||||
|
||||
Reference in New Issue
Block a user