package kafka import ( "context" "producer/internal/logging" "producer/pkg/utils" "strconv" "strings" "sync" "time" kafka "github.com/segmentio/kafka-go" ) // KafkaClient gestiona la conexión con Kafka type KafkaClient struct { brokers []string mu sync.Mutex writers map[string]*kafka.Writer } // NewKafkaClient crea un nuevo cliente Kafka func NewKafkaClient(bootstrapServers string) *KafkaClient { return &KafkaClient{ brokers: strings.Split(bootstrapServers, ","), writers: make(map[string]*kafka.Writer), } } // getWriter obtiene o crea un writer para el topic dado func (kc *KafkaClient) getWriter(topic string) *kafka.Writer { kc.mu.Lock() defer kc.mu.Unlock() if w, ok := kc.writers[topic]; ok { return w } // Determinar RequiredAcks basado en variable de entorno var requiredAcks int if acks := utils.GetEnv("KAFKA_REQUIRED_ACKS", "all"); acks != "all" { if acksNum, err := strconv.Atoi(acks); err == nil { requiredAcks = acksNum } else { requiredAcks = int(kafka.RequireAll) } } else { requiredAcks = int(kafka.RequireAll) } w := kafka.NewWriter(kafka.WriterConfig{ Brokers: kc.brokers, Topic: topic, Balancer: &kafka.LeastBytes{}, RequiredAcks: requiredAcks, Async: utils.GetEnvBool("KAFKA_ASYNC", false), }) kc.writers[topic] = w return w } // Publish publica un mensaje en cualquier topic func (kc *KafkaClient) Publish(ctx context.Context, topic, key string, value []byte) error { writer := kc.getWriter(topic) msg := kafka.Message{ Key: []byte(key), Value: value, Time: time.Now(), } return writer.WriteMessages(ctx, msg) } // Close cierra todos los writers func (kc *KafkaClient) Close() error { kc.mu.Lock() defer kc.mu.Unlock() var err error for _, w := range kc.writers { if e := w.Close(); e != nil { logging.ErrorLogger.Printf("Error cerrando writer: %v", e) err = e } } return err } //package kafka // //import ( // "context" // "producer/pkg/utils" // "strconv" // "strings" // "sync" // "time" // // kafka "github.com/segmentio/kafka-go" //) // //// KafkaClient gestiona la conexión con Kafka //type KafkaClient struct { // brokers []string // mu sync.Mutex // writers map[string]*kafka.Writer //} // //// NewKafkaClient crea un nuevo cliente Kafka //func NewKafkaClient(bootstrapServers string) *KafkaClient { // return &KafkaClient{ // brokers: strings.Split(bootstrapServers, ","), // writers: make(map[string]*kafka.Writer), // } //} // //// getWriter obtiene o crea un writer para el topic dado //func (kc *KafkaClient) getWriter(topic string) *kafka.Writer { // kc.mu.Lock() // defer kc.mu.Unlock() // // if w, ok := kc.writers[topic]; ok { // return w // } // // // Determinar RequiredAcks basado en variable de entorno // requiredAcks := kafka.RequireAll // if acks := utils.GetEnv("KAFKA_REQUIRED_ACKS", "all"); acks != "all" { // if acksNum, err := strconv.Atoi(acks); err == nil { // requiredAcks = kafka.RequiredAcks(acksNum) // } // } // // w := kafka.NewWriter(kafka.WriterConfig{ // Brokers: kc.brokers, // Topic: topic, // Balancer: &kafka.LeastBytes{}, // RequiredAcks: requiredAcks, // Async: utils.GetEnvBool("KAFKA_ASYNC", false), // }) // kc.writers[topic] = w // return w //} // //// Publish publica un mensaje en cualquier topic //func (kc *KafkaClient) Publish(ctx context.Context, topic, key string, value []byte) error { // writer := kc.getWriter(topic) // msg := kafka.Message{ // Key: []byte(key), // Value: value, // Time: time.Now(), // } // return writer.WriteMessages(ctx, msg) //} // //// Close cierra todos los writers //func (kc *KafkaClient) Close() error { // kc.mu.Lock() // defer kc.mu.Unlock() // // var err error // for topic, w := range kc.writers { // if e := w.Close(); e != nil { // err = e // } // } // return err //}