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:
3
_examples/basic/3-router/.validate_example.yml
Normal file
3
_examples/basic/3-router/.validate_example.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
validation_cmd: "go run main.go"
|
||||
timeout: 120
|
||||
expected_output: "Received message: [0-9a-f\\-]+"
|
||||
14
_examples/basic/3-router/go.mod
Normal file
14
_examples/basic/3-router/go.mod
Normal file
@@ -0,0 +1,14 @@
|
||||
module main.go
|
||||
|
||||
go 1.25
|
||||
|
||||
require github.com/ThreeDotsLabs/watermill v1.5.1
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sony/gobreaker v1.0.0 // indirect
|
||||
)
|
||||
26
_examples/basic/3-router/go.sum
Normal file
26
_examples/basic/3-router/go.sum
Normal file
@@ -0,0 +1,26 @@
|
||||
github.com/ThreeDotsLabs/watermill v1.5.1 h1:t5xMivyf9tpmU3iozPqyrCZXHvoV1XQDfihas4sV0fY=
|
||||
github.com/ThreeDotsLabs/watermill v1.5.1/go.mod h1:Uop10dA3VeJWsSvis9qO3vbVY892LARrKAdki6WtXS4=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sony/gobreaker v1.0.0 h1:feX5fGGXSl3dYd4aHZItw+FpHLvvoaqkawKjVNiFMNQ=
|
||||
github.com/sony/gobreaker v1.0.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8=
|
||||
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
135
_examples/basic/3-router/main.go
Normal file
135
_examples/basic/3-router/main.go
Normal file
@@ -0,0 +1,135 @@
|
||||
// Sources for https://watermill.io/learn/getting-started/
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/ThreeDotsLabs/watermill"
|
||||
"github.com/ThreeDotsLabs/watermill/message"
|
||||
"github.com/ThreeDotsLabs/watermill/message/router/middleware"
|
||||
"github.com/ThreeDotsLabs/watermill/message/router/plugin"
|
||||
"github.com/ThreeDotsLabs/watermill/pubsub/gochannel"
|
||||
)
|
||||
|
||||
var (
|
||||
// For this example, we're using just a simple logger implementation,
|
||||
// You probably want to ship your own implementation of `watermill.LoggerAdapter`.
|
||||
logger = watermill.NewStdLogger(false, false)
|
||||
)
|
||||
|
||||
func main() {
|
||||
router, err := message.NewRouter(message.RouterConfig{}, logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// SignalsHandler will gracefully shutdown Router when SIGTERM is received.
|
||||
// You can also close the router by just calling `r.Close()`.
|
||||
router.AddPlugin(plugin.SignalsHandler)
|
||||
|
||||
// Router level middleware are executed for every message sent to the router
|
||||
router.AddMiddleware(
|
||||
// CorrelationID will copy the correlation id from the incoming message's metadata to the produced messages
|
||||
middleware.CorrelationID,
|
||||
|
||||
// The handler function is retried if it returns an error.
|
||||
// After MaxRetries, the message is Nacked and it's up to the PubSub to resend it.
|
||||
middleware.Retry{
|
||||
MaxRetries: 3,
|
||||
InitialInterval: time.Millisecond * 100,
|
||||
Logger: logger,
|
||||
}.Middleware,
|
||||
|
||||
// Recoverer handles panics from handlers.
|
||||
// In this case, it passes them as errors to the Retry middleware.
|
||||
middleware.Recoverer,
|
||||
)
|
||||
|
||||
// For simplicity, we are using the gochannel Pub/Sub here,
|
||||
// You can replace it with any Pub/Sub implementation, it will work the same.
|
||||
pubSub := gochannel.NewGoChannel(gochannel.Config{}, logger)
|
||||
|
||||
// Producing some incoming messages in background
|
||||
go publishMessages(pubSub)
|
||||
|
||||
// AddHandler returns a handler which can be used to add handler level middleware
|
||||
// or to stop handler.
|
||||
handler := router.AddHandler(
|
||||
"struct_handler", // handler name, must be unique
|
||||
"incoming_messages_topic", // topic from which we will read events
|
||||
pubSub,
|
||||
"outgoing_messages_topic", // topic to which we will publish events
|
||||
pubSub,
|
||||
structHandler{}.Handler,
|
||||
)
|
||||
|
||||
// Handler level middleware is only executed for a specific handler
|
||||
// Such middleware can be added the same way the router level ones
|
||||
handler.AddMiddleware(func(h message.HandlerFunc) message.HandlerFunc {
|
||||
return func(message *message.Message) ([]*message.Message, error) {
|
||||
log.Println("executing handler specific middleware for ", message.UUID)
|
||||
|
||||
return h(message)
|
||||
}
|
||||
})
|
||||
|
||||
// just for debug, we are printing all messages received on `incoming_messages_topic`
|
||||
router.AddConsumerHandler(
|
||||
"print_incoming_messages",
|
||||
"incoming_messages_topic",
|
||||
pubSub,
|
||||
printMessages,
|
||||
)
|
||||
|
||||
// just for debug, we are printing all events sent to `outgoing_messages_topic`
|
||||
router.AddConsumerHandler(
|
||||
"print_outgoing_messages",
|
||||
"outgoing_messages_topic",
|
||||
pubSub,
|
||||
printMessages,
|
||||
)
|
||||
|
||||
// Now that all handlers are registered, we're running the Router.
|
||||
// Run is blocking while the router is running.
|
||||
ctx := context.Background()
|
||||
if err := router.Run(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func publishMessages(publisher message.Publisher) {
|
||||
for {
|
||||
msg := message.NewMessage(watermill.NewUUID(), []byte("Hello, world!"))
|
||||
middleware.SetCorrelationID(watermill.NewUUID(), msg)
|
||||
|
||||
log.Printf("sending message %s, correlation id: %s\n", msg.UUID, middleware.MessageCorrelationID(msg))
|
||||
|
||||
if err := publisher.Publish("incoming_messages_topic", msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func printMessages(msg *message.Message) error {
|
||||
fmt.Printf(
|
||||
"\n> Received message: %s\n> %s\n> metadata: %v\n\n",
|
||||
msg.UUID, string(msg.Payload), msg.Metadata,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
type structHandler struct {
|
||||
// we can add some dependencies here
|
||||
}
|
||||
|
||||
func (s structHandler) Handler(msg *message.Message) ([]*message.Message, error) {
|
||||
log.Println("structHandler received message", msg.UUID)
|
||||
|
||||
msg = message.NewMessage(watermill.NewUUID(), []byte("message produced by structHandler"))
|
||||
return message.Messages{msg}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user