83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
package kafka
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"errors"
|
|
"time"
|
|
|
|
kfkgo "github.com/segmentio/kafka-go"
|
|
)
|
|
|
|
type Payload struct {
|
|
Key []byte
|
|
Value []byte
|
|
Headers []kfkgo.Header
|
|
WriterData any
|
|
}
|
|
|
|
func (c *client) WriteMessages(ctx context.Context, payloads ...*Payload) error {
|
|
if len(payloads) == 0 {
|
|
return nil
|
|
}
|
|
|
|
times := 0
|
|
Retry:
|
|
if c.writer == nil {
|
|
c.Lock()
|
|
c.writer = &kfkgo.Writer{
|
|
Addr: kfkgo.TCP(c.address),
|
|
Topic: c.topic,
|
|
Balancer: &kfkgo.Hash{},
|
|
WriteTimeout: 0,
|
|
RequiredAcks: 0,
|
|
Async: false,
|
|
Transport: &kfkgo.Transport{
|
|
DialTimeout: 30 * time.Second,
|
|
TLS: &tls.Config{InsecureSkipVerify: true}, // todo
|
|
SASL: c.mechanism,
|
|
Context: c.ctx,
|
|
},
|
|
AllowAutoTopicCreation: true,
|
|
}
|
|
c.Unlock()
|
|
}
|
|
|
|
now := time.Now()
|
|
|
|
msgs := make([]kfkgo.Message, 0, len(payloads))
|
|
|
|
for _, item := range payloads {
|
|
msgs = append(msgs, kfkgo.Message{
|
|
Key: item.Key,
|
|
Value: item.Value,
|
|
Headers: item.Headers,
|
|
WriterData: item.WriterData,
|
|
Time: now,
|
|
})
|
|
}
|
|
|
|
context.WithoutCancel(ctx)
|
|
if err := c.writer.WriteMessages(ctx, msgs...); err != nil {
|
|
if errors.Is(err, context.DeadlineExceeded) {
|
|
goto HandleError
|
|
}
|
|
|
|
if c.reconnection {
|
|
times++
|
|
c.logger.Warn("kafka.WriteMessage: reconnection after 30 seconds, times = %d, err = %s", times, err.Error())
|
|
time.Sleep(30 * time.Second)
|
|
c.Lock()
|
|
c.writer = nil
|
|
c.Unlock()
|
|
goto Retry
|
|
}
|
|
|
|
HandleError:
|
|
c.logger.Warn("kafka.WriteMessage: err = %s", err.Error())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|