snapshot of https://github.com/ThreeDotsLabs/watermill.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
master / ci (push) Failing after 0s
Some checks failed
master / ci (push) Failing after 0s
This commit is contained in:
152
_examples/basic/1-your-first-app/main.go
Normal file
152
_examples/basic/1-your-first-app/main.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill"
|
||||
"github.com/ThreeDotsLabs/watermill-kafka/v3/pkg/kafka"
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
"github.com/ThreeDotsLabs/watermill/message/router/middleware"
|
||||
"github.com/ThreeDotsLabs/watermill/message/router/plugin"
|
||||
)
|
||||
|
||||
var (
|
||||
brokers = []string{"kafka:9092"}
|
||||
consumeTopic = "events"
|
||||
publishTopic = "events-processed"
|
||||
|
||||
logger = watermill.NewStdLogger(
|
||||
true, // debug
|
||||
false, // trace
|
||||
)
|
||||
marshaler = kafka.DefaultMarshaler{}
|
||||
)
|
||||
|
||||
type event struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
|
||||
type processedEvent struct {
|
||||
ProcessedID int `json:"processed_id"`
|
||||
Time time.Time `json:"time"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
publisher := createPublisher()
|
||||
|
||||
// Subscriber is created with consumer group handler_1
|
||||
subscriber := createSubscriber("handler_1")
|
||||
|
||||
router, err := message.NewRouter(message.RouterConfig{}, logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
router.AddPlugin(plugin.SignalsHandler)
|
||||
router.AddMiddleware(middleware.Recoverer)
|
||||
|
||||
// Adding a handler (multiple handlers can be added)
|
||||
router.AddHandler(
|
||||
"handler_1", // handler name, must be unique
|
||||
consumeTopic, // topic from which messages should be consumed
|
||||
subscriber,
|
||||
publishTopic, // topic to which messages should be published
|
||||
publisher,
|
||||
func(msg *message.Message) ([]*message.Message, error) {
|
||||
consumedPayload := event{}
|
||||
err := json.Unmarshal(msg.Payload, &consumedPayload)
|
||||
if err != nil {
|
||||
// When a handler returns an error, the default behavior is to send a Nack (negative-acknowledgement).
|
||||
// The message will be processed again.
|
||||
//
|
||||
// You can change the default behaviour by using middlewares, like Retry or PoisonQueue.
|
||||
// You can also implement your own middleware.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("received event %+v\n", consumedPayload)
|
||||
|
||||
newPayload, err := json.Marshal(processedEvent{
|
||||
ProcessedID: consumedPayload.ID,
|
||||
Time: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newMessage := message.NewMessage(watermill.NewUUID(), newPayload)
|
||||
|
||||
return []*message.Message{newMessage}, nil
|
||||
},
|
||||
)
|
||||
|
||||
// Simulate incoming events in the background
|
||||
go simulateEvents(publisher)
|
||||
|
||||
if err := router.Run(context.Background()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// createPublisher is a helper function that creates a Publisher, in this case - the Kafka Publisher.
|
||||
func createPublisher() message.Publisher {
|
||||
kafkaPublisher, err := kafka.NewPublisher(
|
||||
kafka.PublisherConfig{
|
||||
Brokers: brokers,
|
||||
Marshaler: marshaler,
|
||||
},
|
||||
logger,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return kafkaPublisher
|
||||
}
|
||||
|
||||
// createSubscriber is a helper function similar to the previous one, but in this case it creates a Subscriber.
|
||||
func createSubscriber(consumerGroup string) message.Subscriber {
|
||||
kafkaSubscriber, err := kafka.NewSubscriber(
|
||||
kafka.SubscriberConfig{
|
||||
Brokers: brokers,
|
||||
Unmarshaler: marshaler,
|
||||
ConsumerGroup: consumerGroup, // every handler will use a separate consumer group
|
||||
},
|
||||
logger,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return kafkaSubscriber
|
||||
}
|
||||
|
||||
// simulateEvents produces events that will be later consumed.
|
||||
func simulateEvents(publisher message.Publisher) {
|
||||
i := 0
|
||||
for {
|
||||
e := event{
|
||||
ID: i,
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = publisher.Publish(consumeTopic, message.NewMessage(
|
||||
watermill.NewUUID(), // internal uuid of the message, useful for debugging
|
||||
payload,
|
||||
))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i++
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user