snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
113
misc/kafka_producer/main.go
Normal file
113
misc/kafka_producer/main.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// kafka_producer produces publish commands to a Kafka topic for Centrifugo to consume.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go run ./misc/kafka_producer/ -broker localhost:29092 -topic centrifugo -channel test -interval 1s
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/twmb/franz-go/pkg/kadm"
|
||||
"github.com/twmb/franz-go/pkg/kgo"
|
||||
)
|
||||
|
||||
type publishRequest struct {
|
||||
Channel string `json:"channel"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
type methodPayload struct {
|
||||
Method string `json:"method"`
|
||||
Payload json.RawMessage `json:"payload"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
broker := flag.String("broker", "localhost:29092", "Kafka broker address")
|
||||
topic := flag.String("topic", "centrifugo", "Kafka topic to produce to")
|
||||
channel := flag.String("channel", "test", "Centrifugo channel to publish to")
|
||||
interval := flag.Duration("interval", time.Second, "Interval between messages")
|
||||
count := flag.Int("count", 0, "Number of messages to send (0 = unlimited)")
|
||||
flag.Parse()
|
||||
|
||||
client, err := kgo.NewClient(kgo.SeedBrokers(*broker))
|
||||
if err != nil {
|
||||
log.Fatal("error creating Kafka client:", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
// Ensure topic exists (use a separate client since kadm.Close closes the underlying kgo client).
|
||||
admClient, err := kgo.NewClient(kgo.SeedBrokers(*broker))
|
||||
if err != nil {
|
||||
log.Fatal("error creating admin client:", err)
|
||||
}
|
||||
adm := kadm.NewClient(admClient)
|
||||
resp, err := adm.CreateTopics(ctx, 1, 1, nil, *topic)
|
||||
if err != nil {
|
||||
log.Fatal("error creating topic:", err)
|
||||
}
|
||||
for _, t := range resp.Sorted() {
|
||||
if t.Err != nil && !strings.Contains(t.Err.Error(), "TOPIC_ALREADY_EXISTS") {
|
||||
log.Fatalf("error creating topic %s: %v", t.Topic, t.Err)
|
||||
}
|
||||
log.Printf("topic %s ready", t.Topic)
|
||||
}
|
||||
adm.Close()
|
||||
|
||||
i := 0
|
||||
for {
|
||||
i++
|
||||
if *count > 0 && i > *count {
|
||||
break
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(map[string]interface{}{
|
||||
"message": fmt.Sprintf("hello #%d", i),
|
||||
"ts": time.Now().UnixMilli(),
|
||||
})
|
||||
|
||||
publishReq, _ := json.Marshal(publishRequest{
|
||||
Channel: *channel,
|
||||
Data: data,
|
||||
})
|
||||
|
||||
msg, _ := json.Marshal(methodPayload{
|
||||
Method: "publish",
|
||||
Payload: publishReq,
|
||||
})
|
||||
|
||||
record := &kgo.Record{
|
||||
Topic: *topic,
|
||||
Value: msg,
|
||||
}
|
||||
|
||||
res := client.ProduceSync(ctx, record)
|
||||
err := res.FirstErr()
|
||||
if err != nil {
|
||||
if ctx.Err() != nil {
|
||||
break
|
||||
}
|
||||
log.Println("error producing:", err)
|
||||
} else {
|
||||
log.Printf("produced message #%d to topic=%s channel=%s %s (offset %d)", i, *topic, *channel, string(data), res[0].Record.Offset)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(*interval):
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user