diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b1b419b..6a0ff4c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,20 +1,17 @@ -name: Go +name: Go tests on: [push] jobs: - build: - name: Test runs-on: ubuntu-latest + strategy: + matrix: + go: [ '1.11.x', '1.12.x', '1.13.x' ] + name: Go ${{ matrix.go }} steps: - - - name: Set up Go 1.12 + - uses: actions/checkout@v1 + - name: Setup go uses: actions/setup-go@v1 with: - go-version: 1.12 - id: go - - - name: Check out code into the Go module directory - uses: actions/checkout@v1 - + go-version: ${{ matrix.go }} - name: Test run: go test ./... -v -mod=vendor -race -count=1 -coverprofile=coverage.txt -covermode=atomic -timeout=120s diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b715616..0000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -sudo: false - -language: go - -env: - global: - - GO111MODULE=on - -go: - - 1.11.x - - 1.12.x - - 1.13.x - -install: false -script: -- go test ./... -v -mod=vendor -race -count=1 -coverprofile=coverage.txt -covermode=atomic -timeout=30s - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index 6976643..adf20e2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Commander 🚀 [![GoDoc](https://godoc.org/github.com/jeroenrinzema/commander?status.svg)](https://godoc.org/github.com/jeroenrinzema/commander) -[![Build Status](https://travis-ci.org/jeroenrinzema/commander.svg?branch=master)](https://travis-ci.org/jeroenrinzema/commander) [![Coverage](https://codecov.io/gh/jeroenrinzema/commander/branch/master/graph/badge.svg)](https://codecov.io/gh/jeroenrinzema/commander) [![Coverage Report](https://goreportcard.com/badge/github.com/jeroenrinzema/commander)](https://goreportcard.com/report/github.com/jeroenrinzema/commander) @@ -9,7 +8,7 @@ Commander is Go library for writing event-driven applications. Enabling event so ## Getting started 1. [🚀 Examples](https://github.com/jeroenrinzema/commander/tree/master/examples) -1. [📚 Documentation](https://godoc.org/github.com/jeroenrinzema/commander) +2. [📚 Documentation](https://godoc.org/github.com/jeroenrinzema/commander) --- diff --git a/dialects/README.md b/dialects/README.md index 14af062..04810bf 100644 --- a/dialects/README.md +++ b/dialects/README.md @@ -1,9 +1,10 @@ # Dialect -A commander dialects is responsible for the consumption/production of messages. -Check out the [dialect interface](https://github.com/jeroenrinzema/commander/blob/master/dialect.go) to see which methods have to be available to a dialect. - -On construction of the commander instance is a connectionstring and available groups passed which is given to the dialect. -The dialect could when nessasery setup/initialize the given groups/connectionstring on for it's targeted protocol (ex: Kafka, RabbitMQ) - -Below is a example mocking dialect shown that allowes messages to be consumed and produced in-memory. This is a very simple example and is not safe for concurrent actions. \ No newline at end of file +- [Kafka](https://github.com/jeroenrinzema/commander/tree/master/dialects/kafka) +- [Mock](https://github.com/jeroenrinzema/commander/tree/master/dialects/mock) +- Redis +- RabbitMQ +- SQL +- Websocket +- io.Reader/io.Writer +- NATS \ No newline at end of file diff --git a/dialects/kafka/consumer/main.go b/dialects/kafka/consumer/main.go index 968dbf0..99662b0 100644 --- a/dialects/kafka/consumer/main.go +++ b/dialects/kafka/consumer/main.go @@ -171,7 +171,7 @@ func (client *Client) Claim(consumed *sarama.ConsumerMessage) (err error) { select { case subscription.messages <- message: - result := message.Await() + result := message.Finally() if result != nil { return ErrRetry } diff --git a/dialects/kafka/main.go b/dialects/kafka/main.go index 22c0997..7f95574 100644 --- a/dialects/kafka/main.go +++ b/dialects/kafka/main.go @@ -10,7 +10,6 @@ import ( // Dialect represents the kafka dialect type Dialect struct { Connection Config - Topics []types.Topic Config *sarama.Config consumer *consumer.Client @@ -53,14 +52,9 @@ func (dialect *Dialect) Producer() types.Producer { return dialect.producer } -// Assigned is called when a topic gets created -func (dialect *Dialect) Assigned(topic types.Topic) { - dialect.Topics = append(dialect.Topics, topic) -} - // Open opens a kafka consumer and producer -func (dialect *Dialect) Open() (err error) { - err = dialect.consumer.Connect(dialect.Connection.Brokers, dialect.Config, dialect.Connection.InitialOffset, dialect.Topics...) +func (dialect *Dialect) Open(topics []types.Topic) (err error) { + err = dialect.consumer.Connect(dialect.Connection.Brokers, dialect.Config, dialect.Connection.InitialOffset, topics...) if err != nil { return err } diff --git a/dialects/kafka/metadata/message.go b/dialects/kafka/metadata/message.go index 9cc000a..940effa 100644 --- a/dialects/kafka/metadata/message.go +++ b/dialects/kafka/metadata/message.go @@ -8,6 +8,7 @@ import ( "github.com/Shopify/sarama" "github.com/jeroenrinzema/commander" + "github.com/jeroenrinzema/commander/internal/metadata" "github.com/jeroenrinzema/commander/internal/types" ) @@ -25,9 +26,9 @@ func MessageFromMessage(consumed *sarama.ConsumerMessage) *commander.Message { Data: consumed.Value, Key: consumed.Key, Timestamp: consumed.Timestamp, - Ctx: ctx, } + message.NewCtx(ctx) headers := map[string][]string{} headers: @@ -61,7 +62,7 @@ headers: message.EOS = message.EOS.Parse(string(record.Value)) break case HeaderParentID: - message.Ctx = types.NewParentIDContext(message.Ctx, types.ParentID(record.Value)) + message.NewCtx(metadata.NewParentIDContext(message.Ctx(), metadata.ParentID(record.Value))) break case HeaderParentTimestamp: unix, err := strconv.ParseInt(string(record.Value), 10, 64) @@ -69,11 +70,11 @@ headers: continue headers } - time := types.ParentTimestamp(time.Unix(0, unix)) - message.Ctx = types.NewParentTimestampContext(message.Ctx, time) + time := metadata.ParentTimestamp(time.Unix(0, unix)) + message.NewCtx(metadata.NewParentTimestampContext(message.Ctx(), time)) break default: - headers[key] = strings.Split(string(record.Value), types.HeaderValueDevider) + headers[key] = strings.Split(string(record.Value), metadata.HeaderValueDevider) break } } @@ -106,7 +107,7 @@ func MessageToMessage(produce *commander.Message) *sarama.ProducerMessage { }, } - parent, has := types.ParentIDFromContext(produce.Ctx) + parent, has := metadata.ParentIDFromContext(produce.Ctx()) if has { headers = append(headers, sarama.RecordHeader{ Key: []byte(HeaderParentID), @@ -114,7 +115,7 @@ func MessageToMessage(produce *commander.Message) *sarama.ProducerMessage { }) } - timestamp, has := types.ParentTimestampFromContext(produce.Ctx) + timestamp, has := metadata.ParentTimestampFromContext(produce.Ctx()) if has { headers = append(headers, sarama.RecordHeader{ Key: []byte(HeaderParentTimestamp), @@ -122,7 +123,7 @@ func MessageToMessage(produce *commander.Message) *sarama.ProducerMessage { }) } - kv, has := types.HeaderFromContext(produce.Ctx) + kv, has := metadata.HeaderFromContext(produce.Ctx()) if has { for key, value := range kv { headers = append(headers, sarama.RecordHeader{ diff --git a/dialects/mock/consumer.go b/dialects/mock/consumer.go index 8a73d24..eb9ca68 100644 --- a/dialects/mock/consumer.go +++ b/dialects/mock/consumer.go @@ -44,7 +44,7 @@ func (consumer *Consumer) Emit(message *types.Message) { for _, subscription := range collection.list { message.Reset() subscription.messages <- message - message.Await() + message.Finally() } collection.mutex.Unlock() close(resolved) diff --git a/dialects/mock/consumer_test.go b/dialects/mock/consumer_test.go index 570ec3b..f6d8e3b 100644 --- a/dialects/mock/consumer_test.go +++ b/dialects/mock/consumer_test.go @@ -14,9 +14,10 @@ func TestConsumerConsumption(t *testing.T) { topic := types.NewTopic("mock", dialect, types.EventMessage, types.DefaultMode) message := types.Message{ Topic: topic, - Ctx: context.Background(), } + message.NewCtx(context.Background()) + sink := make(chan bool) messages, err := dialect.Consumer().Subscribe(topic) if err != nil { @@ -25,7 +26,7 @@ func TestConsumerConsumption(t *testing.T) { go func() { for message := range messages { - message.Next() + message.Ack() close(sink) } }() diff --git a/dialects/mock/main.go b/dialects/mock/main.go index fda6e27..892f781 100644 --- a/dialects/mock/main.go +++ b/dialects/mock/main.go @@ -47,15 +47,10 @@ type Dialect struct { // Open notifies a dialect to open the dialect. // No further topic assignments should be made. -func (dialect *Dialect) Open() error { +func (dialect *Dialect) Open([]types.Topic) error { return nil } -// Assigned notifies a dialect about the assignment of the given topic -func (dialect *Dialect) Assigned(types.Topic) { - // ignore... -} - // Consumer returns the dialect consumer func (dialect *Dialect) Consumer() types.Consumer { return dialect.consumer diff --git a/dialects/mock/main_test.go b/dialects/mock/main_test.go index 5d32682..7ff8dc1 100644 --- a/dialects/mock/main_test.go +++ b/dialects/mock/main_test.go @@ -6,7 +6,7 @@ import "testing" func TestNewDialectConstruction(t *testing.T) { dialect := NewDialect() - dialect.Open() + dialect.Open(nil) if dialect.Consumer() == nil { t.Fatal("no dialect consumer") diff --git a/dialects/mock/producer_test.go b/dialects/mock/producer_test.go index 7fb2242..75606d4 100644 --- a/dialects/mock/producer_test.go +++ b/dialects/mock/producer_test.go @@ -13,9 +13,9 @@ func TestProducerProduction(t *testing.T) { topic := types.NewTopic("mock", dialect, types.EventMessage, types.DefaultMode) message := types.Message{ Topic: topic, - Ctx: context.Background(), } + message.NewCtx(context.Background()) err := dialect.Producer().Publish(&message) if err != nil { t.Fatal(err) diff --git a/examples/kafka/go.sum b/examples/kafka/go.sum index 957dafc..2a7498d 100644 --- a/examples/kafka/go.sum +++ b/examples/kafka/go.sum @@ -9,6 +9,12 @@ github.com/Shopify/sarama v1.22.1 h1:exyEsKLGyCsDiqpV5Lr4slFi8ev2KiM3cP1KZ6vnCQ0 github.com/Shopify/sarama v1.22.1/go.mod h1:FRzlvRpMFO/639zY1SDxUxkqH97Y0ndM5CbGj6oG3As= github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 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= @@ -20,18 +26,28 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jeroenrinzema/commander/dialects/kafka v0.0.0-20190406211118-d65d4aaec57d/go.mod h1:p8F8ymzu3CGQA/eVQeb9StOUMmOzK0M9a2f/dBU9dck= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190430202912-8fe70c0e1b5a/go.mod h1:rOw7O00SkE/3oR77184Etqs7THPiokOaVrub4mSzePA= @@ -41,8 +57,17 @@ github.com/jeroenrinzema/commander/examples/mock v0.0.0-20190613124800-6c8bc78e3 github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0DeSCXOO2GXIi4n+FUWGS6o/pCI/ZBpsKebVuW6hIj8= github.com/jeroenrinzema/commander/examples/streaming v0.0.0-20190702094603-24861dd4d416/go.mod h1:7463oz3hsyxpJu+n9qvoXo63DISG29e8OXbSD/Jpx10= github.com/jeroenrinzema/commander/examples/zipkin v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0kH96eT7K8FRLOQj/93XMym10lFwlLKJD9MSthr90z0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -50,11 +75,22 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -64,6 +100,7 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -75,18 +112,23 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/kafka/main.go b/examples/kafka/main.go index 47faff0..489def3 100644 --- a/examples/kafka/main.go +++ b/examples/kafka/main.go @@ -63,7 +63,7 @@ func main() { key, err := uuid.NewV4() if err != nil { // Mark the message to be retried, this will reset the offset of the message topic, parition to the original message offset - message.Retry(err) + message.Nack() return } @@ -94,7 +94,7 @@ func main() { return } - event.Next() + event.Ack() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(event) diff --git a/examples/kafka/vendor/github.com/jeroenrinzema/commander/group.go b/examples/kafka/vendor/github.com/jeroenrinzema/commander/group.go index 8b9fd9e..5fa4847 100644 --- a/examples/kafka/vendor/github.com/jeroenrinzema/commander/group.go +++ b/examples/kafka/vendor/github.com/jeroenrinzema/commander/group.go @@ -247,12 +247,12 @@ func (group *Group) ProduceEvent(event Event) error { func (group *Group) Publish(message *Message) error { group.Middleware.Emit(middleware.BeforePublish, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) defer group.Middleware.Emit(middleware.AfterPublish, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) err := message.Topic.Dialect.Producer().Publish(message) @@ -289,7 +289,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, for message := range messages { group.Middleware.Emit(middleware.BeforeMessageConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) sink <- message @@ -297,7 +297,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(middleware.AfterMessageConsumed, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }(messages) @@ -328,20 +328,20 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(middleware.BeforeActionConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) switch sort { case EventMessage: event := Event{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } event.Populate(message) value = event case CommandMessage: command := Command{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } command.Populate(message) @@ -357,7 +357,7 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(middleware.AfterActionConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }() diff --git a/examples/mock-multiple-groups/go.sum b/examples/mock-multiple-groups/go.sum index 91b1a9c..3a5eacb 100644 --- a/examples/mock-multiple-groups/go.sum +++ b/examples/mock-multiple-groups/go.sum @@ -1,21 +1,38 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190530123436-e19f7e417aeb/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= @@ -25,19 +42,42 @@ github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190530 github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0DeSCXOO2GXIi4n+FUWGS6o/pCI/ZBpsKebVuW6hIj8= github.com/jeroenrinzema/commander/examples/streaming v0.0.0-20190702094603-24861dd4d416/go.mod h1:7463oz3hsyxpJu+n9qvoXo63DISG29e8OXbSD/Jpx10= github.com/jeroenrinzema/commander/examples/zipkin v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0kH96eT7K8FRLOQj/93XMym10lFwlLKJD9MSthr90z0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -45,16 +85,21 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/mock-multiple-groups/main.go b/examples/mock-multiple-groups/main.go index f866854..6c0670d 100644 --- a/examples/mock-multiple-groups/main.go +++ b/examples/mock-multiple-groups/main.go @@ -72,7 +72,7 @@ func main() { return } - event.Next() + event.Ack() if event.Status != commander.StatusOK { writer.Error("NotAvailable", commander.StatusNotFound, err) @@ -102,14 +102,14 @@ func main() { return } - event.Next() + event.Ack() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(event) }) fmt.Println("Http server running at :8080") - fmt.Println("Send a http request to /purchase to simulate a 'sync' purchase command") + fmt.Println("Send a http request to / to simulate a 'sync' purchase command") err := http.ListenAndServe(":8080", nil) if err != nil { diff --git a/examples/mock-multiple-groups/vendor/github.com/jeroenrinzema/commander/group.go b/examples/mock-multiple-groups/vendor/github.com/jeroenrinzema/commander/group.go index 4a58ea8..dbc4502 100644 --- a/examples/mock-multiple-groups/vendor/github.com/jeroenrinzema/commander/group.go +++ b/examples/mock-multiple-groups/vendor/github.com/jeroenrinzema/commander/group.go @@ -246,12 +246,12 @@ func (group *Group) ProduceEvent(event Event) error { func (group *Group) Publish(message *Message) error { group.Middleware.Emit(BeforePublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) defer group.Middleware.Emit(AfterPublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) err := message.Topic.Dialect.Producer().Publish(message) @@ -288,7 +288,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, for message := range messages { group.Middleware.Emit(BeforeMessageConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) sink <- message @@ -296,7 +296,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(AfterMessageConsumed, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }(messages) @@ -327,20 +327,20 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(BeforeActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) switch sort { case EventMessage: event := Event{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } event.Populate(message) value = event case CommandMessage: command := Command{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } command.Populate(message) @@ -356,7 +356,7 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(AfterActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }() diff --git a/examples/mock/go.sum b/examples/mock/go.sum index 3d2b80d..2dbad2c 100644 --- a/examples/mock/go.sum +++ b/examples/mock/go.sum @@ -6,15 +6,28 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -27,11 +40,14 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -44,22 +60,45 @@ github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190530 github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0DeSCXOO2GXIi4n+FUWGS6o/pCI/ZBpsKebVuW6hIj8= github.com/jeroenrinzema/commander/examples/streaming v0.0.0-20190702094603-24861dd4d416/go.mod h1:7463oz3hsyxpJu+n9qvoXo63DISG29e8OXbSD/Jpx10= github.com/jeroenrinzema/commander/examples/zipkin v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0kH96eT7K8FRLOQj/93XMym10lFwlLKJD9MSthr90z0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -88,7 +127,9 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= @@ -100,6 +141,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -122,6 +164,7 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/mock/main.go b/examples/mock/main.go index 612f054..0ae7419 100644 --- a/examples/mock/main.go +++ b/examples/mock/main.go @@ -33,7 +33,7 @@ func main() { group.HandleFunc(commander.CommandMessage, "example", func(message *commander.Message, writer commander.Writer) { key, err := uuid.NewV4() if err != nil { - message.Retry(err) + message.Nack() return } @@ -56,7 +56,7 @@ func main() { return } - event.Next() + event.Ack() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(event) diff --git a/examples/mock/vendor/github.com/jeroenrinzema/commander/group.go b/examples/mock/vendor/github.com/jeroenrinzema/commander/group.go index 4a58ea8..dbc4502 100644 --- a/examples/mock/vendor/github.com/jeroenrinzema/commander/group.go +++ b/examples/mock/vendor/github.com/jeroenrinzema/commander/group.go @@ -246,12 +246,12 @@ func (group *Group) ProduceEvent(event Event) error { func (group *Group) Publish(message *Message) error { group.Middleware.Emit(BeforePublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) defer group.Middleware.Emit(AfterPublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) err := message.Topic.Dialect.Producer().Publish(message) @@ -288,7 +288,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, for message := range messages { group.Middleware.Emit(BeforeMessageConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) sink <- message @@ -296,7 +296,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(AfterMessageConsumed, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }(messages) @@ -327,20 +327,20 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(BeforeActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) switch sort { case EventMessage: event := Event{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } event.Populate(message) value = event case CommandMessage: command := Command{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } command.Populate(message) @@ -356,7 +356,7 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(AfterActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }() diff --git a/examples/streaming/go.sum b/examples/streaming/go.sum index 91b1a9c..3a5eacb 100644 --- a/examples/streaming/go.sum +++ b/examples/streaming/go.sum @@ -1,21 +1,38 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190530123436-e19f7e417aeb/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= @@ -25,19 +42,42 @@ github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190530 github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0DeSCXOO2GXIi4n+FUWGS6o/pCI/ZBpsKebVuW6hIj8= github.com/jeroenrinzema/commander/examples/streaming v0.0.0-20190702094603-24861dd4d416/go.mod h1:7463oz3hsyxpJu+n9qvoXo63DISG29e8OXbSD/Jpx10= github.com/jeroenrinzema/commander/examples/zipkin v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0kH96eT7K8FRLOQj/93XMym10lFwlLKJD9MSthr90z0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -45,16 +85,21 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/streaming/main.go b/examples/streaming/main.go index 75989f5..a978877 100644 --- a/examples/streaming/main.go +++ b/examples/streaming/main.go @@ -9,7 +9,7 @@ import ( "github.com/gofrs/uuid" "github.com/jeroenrinzema/commander" "github.com/jeroenrinzema/commander/dialects/mock" - "github.com/jeroenrinzema/commander/internal/types" + "github.com/jeroenrinzema/commander/internal/metadata" ) func main() { @@ -67,14 +67,14 @@ func main() { // Consume and filter messages based on their event ID. // The connection is closed when a timeout is reached of a EOS event is consumed. for message := range messages { - parent, has := types.ParentIDFromContext(message.Ctx) - if !has || parent != types.ParentID(command.ID) { - message.Next() + parent, has := metadata.ParentIDFromContext(message.Ctx()) + if !has || parent != metadata.ParentID(command.ID) { + message.Ack() continue } json.NewEncoder(w).Encode(message) - message.Next() + message.Ack() if message.EOS { break diff --git a/examples/streaming/vendor/github.com/jeroenrinzema/commander/group.go b/examples/streaming/vendor/github.com/jeroenrinzema/commander/group.go index 4a58ea8..dbc4502 100644 --- a/examples/streaming/vendor/github.com/jeroenrinzema/commander/group.go +++ b/examples/streaming/vendor/github.com/jeroenrinzema/commander/group.go @@ -246,12 +246,12 @@ func (group *Group) ProduceEvent(event Event) error { func (group *Group) Publish(message *Message) error { group.Middleware.Emit(BeforePublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) defer group.Middleware.Emit(AfterPublish, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) err := message.Topic.Dialect.Producer().Publish(message) @@ -288,7 +288,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, for message := range messages { group.Middleware.Emit(BeforeMessageConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) sink <- message @@ -296,7 +296,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(AfterMessageConsumed, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }(messages) @@ -327,20 +327,20 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(BeforeActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) switch sort { case EventMessage: event := Event{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } event.Populate(message) value = event case CommandMessage: command := Command{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } command.Populate(message) @@ -356,7 +356,7 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(AfterActionConsumption, &MiddlewareEvent{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }() diff --git a/examples/zipkin/go.sum b/examples/zipkin/go.sum index a868b82..f50e831 100644 --- a/examples/zipkin/go.sum +++ b/examples/zipkin/go.sum @@ -1,23 +1,40 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190530123436-e19f7e417aeb/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= github.com/jeroenrinzema/commander/examples/kafka v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:VW4mbxUMl4lofIwZz4mOZglXHzqWQ4HD25qMvAsNEJo= @@ -27,20 +44,43 @@ github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190530 github.com/jeroenrinzema/commander/examples/mock-multiple-groups v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0DeSCXOO2GXIi4n+FUWGS6o/pCI/ZBpsKebVuW6hIj8= github.com/jeroenrinzema/commander/examples/streaming v0.0.0-20190702094603-24861dd4d416/go.mod h1:7463oz3hsyxpJu+n9qvoXo63DISG29e8OXbSD/Jpx10= github.com/jeroenrinzema/commander/examples/zipkin v0.0.0-20190613124800-6c8bc78e3138/go.mod h1:0kH96eT7K8FRLOQj/93XMym10lFwlLKJD9MSthr90z0= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6 h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtLXHPBo= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -48,17 +88,22 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/examples/zipkin/main.go b/examples/zipkin/main.go index 45e6c9c..c56a6e0 100644 --- a/examples/zipkin/main.go +++ b/examples/zipkin/main.go @@ -45,7 +45,7 @@ func main() { panic(err) } - client.Middleware.Use(tracing) + client.Use(tracing) /** * HandleFunc handles an "example" command. Once a command with the action "example" is @@ -68,7 +68,7 @@ func main() { key := uuid.Must(uuid.NewV4()).Bytes() command := commander.NewMessage("example", 1, key, nil) - command.Ctx = metadata.NewSpanConsumeContext(command.Ctx, span) + command.NewCtx(metadata.NewSpanConsumeContext(command.Ctx(), span)) event, err := group.SyncCommand(command) if err != nil { @@ -77,9 +77,9 @@ func main() { return } - event.Next() + event.Ack() - span, has := metadata.SpanConsumeFromContext(event.Ctx) + span, has := metadata.SpanConsumeFromContext(event.Ctx()) if has { ctx := span.Context() w.Header().Set("X-Tracing", ctx.TraceID.String()) diff --git a/examples/zipkin/vendor/github.com/jeroenrinzema/commander/group.go b/examples/zipkin/vendor/github.com/jeroenrinzema/commander/group.go index c4ca4f8..3cc704f 100644 --- a/examples/zipkin/vendor/github.com/jeroenrinzema/commander/group.go +++ b/examples/zipkin/vendor/github.com/jeroenrinzema/commander/group.go @@ -254,12 +254,12 @@ func (group *Group) ProduceEvent(event Event) error { func (group *Group) Publish(message *Message) error { group.Middleware.Emit(middleware.BeforePublish, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) defer group.Middleware.Emit(middleware.AfterPublish, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) err := message.Topic.Dialect.Producer().Publish(message) @@ -302,7 +302,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(middleware.BeforeMessageConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) sink <- message @@ -310,7 +310,7 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, group.Middleware.Emit(middleware.AfterMessageConsumed, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }(messages) @@ -346,20 +346,20 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(middleware.BeforeActionConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) switch sort { case EventMessage: event := Event{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } event.Populate(message) value = event case CommandMessage: command := Command{ - Ctx: message.Ctx, + Ctx: message.Ctx(), } command.Populate(message) @@ -375,7 +375,7 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H group.Middleware.Emit(middleware.AfterActionConsumption, &middleware.Event{ Value: message, - Ctx: message.Ctx, + Ctx: message.Ctx(), }) } }() diff --git a/examples/zipkin/vendor/github.com/jeroenrinzema/commander/middleware/zipkin/main.go b/examples/zipkin/vendor/github.com/jeroenrinzema/commander/middleware/zipkin/main.go index 393edd9..503118d 100644 --- a/examples/zipkin/vendor/github.com/jeroenrinzema/commander/middleware/zipkin/main.go +++ b/examples/zipkin/vendor/github.com/jeroenrinzema/commander/middleware/zipkin/main.go @@ -107,7 +107,7 @@ func (service *Zipkin) BeforeConsume(event *middleware.Event) error { action := message.Headers[commander.ActionHeader] name := "commander.consume." + action span := service.Tracer.StartSpan(name, options...) - message.Ctx = context.WithValue(message.Ctx, CtxSpanKeyConsume, span) + message.Ctx() = context.WithValue(message.Ctx(), CtxSpanKeyConsume, span) span.Tag(ActionTag, message.Headers[commander.ActionHeader]) span.Tag(StatusTag, message.Headers[commander.StatusHeader]) @@ -151,7 +151,7 @@ func (service *Zipkin) BeforePublish(event *middleware.Event) error { name := "commander.produce" span := service.Tracer.StartSpan(name, zipkin.Kind(model.Consumer), zipkin.Parent(msp.Context())) - message.Ctx = context.WithValue(message.Ctx, CtxSpanKeyProduce, span) + message.Ctx() = context.WithValue(message.Ctx(), CtxSpanKeyProduce, span) span.Tag(ActionTag, message.Headers[commander.ActionHeader]) span.Tag(StatusTag, message.Headers[commander.StatusHeader]) diff --git a/go.mod b/go.mod index 75c006f..3bd7fbc 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.12 require ( github.com/Shopify/sarama v1.19.0 + github.com/ThreeDotsLabs/watermill v1.0.0 // indirect github.com/gofrs/uuid v3.2.0+incompatible github.com/openzipkin/zipkin-go v0.1.6 github.com/sirupsen/logrus v1.4.2 diff --git a/go.sum b/go.sum index b29e4d5..ce41b8a 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,18 @@ +cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/ThreeDotsLabs/watermill v1.0.0 h1:jkKDp5aFz/m4eHr8kntbVxjOnseew6fv/nwE7VmFHmc= +github.com/ThreeDotsLabs/watermill v1.0.0/go.mod h1:gjVFKc8aN+vmEHw3pA0kh4mmuwHe02nyfghb6IWWiKE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +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/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU= @@ -13,24 +22,43 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -40,35 +68,55 @@ github.com/openzipkin/zipkin-go v0.1.6 h1:yXiysv1CSK7Q5yjGy1710zZGnsbMUIjluWBxtL github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/renstrom/shortuuid v3.0.0+incompatible/go.mod h1:n18Ycpn8DijG+h/lLBQVnGKv1BCtTeXo8KKSbBOrQ8c= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= diff --git a/group.go b/group.go index 4e467f7..ccede2a 100644 --- a/group.go +++ b/group.go @@ -8,8 +8,10 @@ import ( "time" "github.com/jeroenrinzema/commander/internal/circuit" - "github.com/jeroenrinzema/commander/middleware" + "github.com/jeroenrinzema/commander/internal/metadata" + "github.com/jeroenrinzema/commander/internal/options" "github.com/jeroenrinzema/commander/internal/types" + "github.com/jeroenrinzema/commander/middleware" log "github.com/sirupsen/logrus" ) @@ -19,22 +21,9 @@ var ( ErrNoAction = errors.New("no action defined") ) -// EventType represents a middleware event type -type EventType string - -// Globally available event types -const ( - AfterActionConsumption = EventType("AfterActionConsumption") - BeforeActionConsumption = EventType("BeforeActionConsumption") - BeforeMessageConsumption = EventType("BeforeMessageConsumption") - AfterMessageConsumed = EventType("AfterMessageConsumed") - BeforePublish = EventType("BeforePublish") - AfterPublish = EventType("AfterPublish") -) - // NewGroup initializes a new commander group. -func NewGroup(definitions ...types.GroupOption) *Group { - options := types.NewGroupOptions(definitions) +func NewGroup(definitions ...options.GroupOption) *Group { + options := options.NewGroupOptions(definitions) group := &Group{ Timeout: options.Timeout, @@ -58,10 +47,10 @@ func NewGroup(definitions ...types.GroupOption) *Group { // commands and events could be consumed and produced to. The amount of retries // attempted before a error is thrown could also be defined in a group. type Group struct { - Middleware *middleware.Client + Middleware middleware.UseImpl Timeout time.Duration Topics []types.Topic - Codec types.Codec + Codec options.Codec Retries int8 logger *log.Logger } @@ -72,8 +61,8 @@ type Close = types.Close // Next indicates that the next message could be called type Next = types.Next -// Handle message handle message, writer implementation -type Handle = types.Handle +// HandlerFunc message handle message, writer implementation +type HandlerFunc = types.HandlerFunc // Handler interface handle wrapper type Handler = types.Handler @@ -109,13 +98,13 @@ func (group *Group) SyncCommand(message *Message) (event *Message, err error) { return event, err } - event, err = group.AwaitEOS(messages, types.ParentID(message.ID)) + event, err = group.AwaitEOS(messages, metadata.ParentID(message.ID)) return event, err } // AwaitEventWithAction awaits till the first event for the given parent id and action is consumed. // If no events are returned within the given timeout period a error will be returned. -func (group *Group) AwaitEventWithAction(messages <-chan *types.Message, parent types.ParentID, action string) (message *Message, err error) { +func (group *Group) AwaitEventWithAction(messages <-chan *types.Message, parent metadata.ParentID, action string) (message *Message, err error) { group.logger.Debug("awaiting action") if action == "" { @@ -129,13 +118,13 @@ func (group *Group) AwaitEventWithAction(messages <-chan *types.Message, parent } if message.Action != action { - message.Next() + message.Ack() continue } - id, has := types.ParentIDFromContext(message.Ctx) + id, has := metadata.ParentIDFromContext(message.Ctx()) if !has || parent != id { - message.Next() + message.Ack() continue } @@ -147,7 +136,7 @@ func (group *Group) AwaitEventWithAction(messages <-chan *types.Message, parent // AwaitMessage awaits till the first message is consumed for the given parent id. // If no events are returned within the given timeout period a error will be returned. -func (group *Group) AwaitMessage(messages <-chan *types.Message, parent types.ParentID) (message *Message, err error) { +func (group *Group) AwaitMessage(messages <-chan *types.Message, parent metadata.ParentID) (message *Message, err error) { group.logger.Debug("awaiting message") for { @@ -156,9 +145,9 @@ func (group *Group) AwaitMessage(messages <-chan *types.Message, parent types.Pa return nil, ErrTimeout } - id, has := types.ParentIDFromContext(message.Ctx) + id, has := metadata.ParentIDFromContext(message.Ctx()) if !has || parent != id { - message.Next() + message.Ack() continue } @@ -170,7 +159,7 @@ func (group *Group) AwaitMessage(messages <-chan *types.Message, parent types.Pa // AwaitEOS awaits till the final event stream message is emitted. // If no events are returned within the given timeout period a error will be returned. -func (group *Group) AwaitEOS(messages <-chan *types.Message, parent types.ParentID) (message *Message, err error) { +func (group *Group) AwaitEOS(messages <-chan *types.Message, parent metadata.ParentID) (message *Message, err error) { group.logger.Debug("awaiting EOS") for { @@ -180,13 +169,13 @@ func (group *Group) AwaitEOS(messages <-chan *types.Message, parent types.Parent } if !message.EOS { - message.Next() + message.Ack() continue } - id, has := types.ParentIDFromContext(message.Ctx) + id, has := metadata.ParentIDFromContext(message.Ctx()) if !has || parent != id { - message.Next() + message.Ack() continue } @@ -220,7 +209,7 @@ func (group *Group) FetchTopics(t types.MessageType, m types.TopicMode) []types. // A error is returned if anything went wrong in the process. If no command key is set will the command id be used. func (group *Group) ProduceCommand(message *Message) error { if message.Key == nil { - message.Key = types.Key([]byte(message.ID)) + message.Key = metadata.Key([]byte(message.ID)) } topics := group.FetchTopics(CommandMessage, ProduceMode) @@ -252,7 +241,7 @@ func (group *Group) ProduceCommand(message *Message) error { // A error is returned if anything went wrong in the process. func (group *Group) ProduceEvent(message *Message) error { if message.Key == nil { - message.Key = types.Key([]byte(message.ID)) + message.Key = metadata.Key([]byte(message.ID)) } topics := group.FetchTopics(EventMessage, ProduceMode) @@ -283,9 +272,6 @@ func (group *Group) ProduceEvent(message *Message) error { // Publish publishes the given message to the group producer. // All middleware subscriptions are called before publishing the message. func (group *Group) Publish(message *Message) error { - group.Middleware.Emit(message.Ctx, BeforePublish, message) - defer group.Middleware.Emit(message.Ctx, AfterPublish, message) - err := message.Topic.Dialect().Producer().Publish(message) if err != nil { return err @@ -323,18 +309,14 @@ func (group *Group) NewConsumer(sort types.MessageType) (<-chan *types.Message, go func() { for message := range messages { if !breaker.Safe() { - message.Next() + message.Ack() return } group.logger.Debug("message consumer consumed message") mutex.Lock() - group.Middleware.Emit(message.Ctx, BeforeMessageConsumption, message) - sink <- message - - group.Middleware.Emit(message.Ctx, AfterMessageConsumed, message) mutex.Unlock() } }() @@ -392,7 +374,7 @@ func (group *Group) Handle(sort types.MessageType, action string, handler Handle // HandleFunc awaits messages from the given MessageType and action. // Once a message is received is the callback method called with the received command. // The handle is closed once the consumer receives a close signal. -func (group *Group) HandleFunc(sort types.MessageType, action string, callback Handle) (Close, error) { +func (group *Group) HandleFunc(sort types.MessageType, action string, callback HandlerFunc) (Close, error) { return group.HandleContext( WithAction(action), WithMessageType(sort), @@ -404,8 +386,8 @@ func (group *Group) HandleFunc(sort types.MessageType, action string, callback H } // HandleContext constructs a handle context based on the given definitions. -func (group *Group) HandleContext(definitions ...types.HandleOption) (Close, error) { - options := types.NewHandleOptions(definitions) +func (group *Group) HandleContext(definitions ...options.HandlerOption) (Close, error) { + options := options.NewHandlerOptions(definitions) group.logger.Debugf("setting up new consumer handle: %d, %s", options.MessageType, options.Action) messages, closing, err := group.NewConsumer(options.MessageType) @@ -416,7 +398,7 @@ func (group *Group) HandleContext(definitions ...types.HandleOption) (Close, err go func() { for message := range messages { if options.Action != "" && message.Action != options.Action { - message.Next() + message.Ack() continue } @@ -424,14 +406,10 @@ func (group *Group) HandleContext(definitions ...types.HandleOption) (Close, err group.Codec.Unmarshal(message.Data, &schema) message.NewSchema(schema) - group.Middleware.Emit(message.Ctx, BeforeActionConsumption, message) - writer := NewWriter(group, message) options.Callback(message, writer) - message.Next() - - group.Middleware.Emit(message.Ctx, AfterActionConsumption, message) + message.Ack() } }() diff --git a/group_test.go b/group_test.go index 0250e6f..8852182 100644 --- a/group_test.go +++ b/group_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/jeroenrinzema/commander/dialects/mock" + "github.com/jeroenrinzema/commander/internal/metadata" "github.com/jeroenrinzema/commander/internal/types" ) @@ -103,14 +104,14 @@ func TestSyncCommand(t *testing.T) { }) event, err := group.SyncCommand(message) - event.Next() + event.Ack() if err != nil { t.Error(err) } - parent, has := types.ParentIDFromContext(event.Ctx) - if !has || parent != types.ParentID(message.ID) { + parent, has := metadata.ParentIDFromContext(event.Ctx()) + if !has || parent != metadata.ParentID(message.ID) { t.Error("command id and parent do not match") } } @@ -139,12 +140,12 @@ func BenchmarkSyncCommand(b *testing.B) { b.Error(err) } - parent, has := types.ParentIDFromContext(event.Ctx) - if !has || parent != types.ParentID(message.ID) { + parent, has := metadata.ParentIDFromContext(event.Ctx()) + if !has || parent != metadata.ParentID(message.ID) { b.Error("command id and parent do not match") } - event.Next() + event.Ack() } } @@ -172,8 +173,8 @@ func TestAwaitEvent(t *testing.T) { defer closer() - message, err := group.AwaitMessage(messages, types.ParentID(parent.ID)) - message.Next() + message, err := group.AwaitMessage(messages, metadata.ParentID(parent.ID)) + message.Ack() if err != nil { t.Fatal(err) @@ -206,12 +207,12 @@ func TestAwaitEventAction(t *testing.T) { defer closer() - message, err := group.AwaitEventWithAction(messages, types.ParentID(parent.ID), action) + message, err := group.AwaitEventWithAction(messages, metadata.ParentID(parent.ID), action) if err != nil { t.Error(err) } - message.Next() + message.Ack() } // TestAwaitEventIgnoreParent tests if plausible to await a event with action @@ -238,12 +239,12 @@ func TestAwaitEventIgnoreParent(t *testing.T) { defer closer() - message, err := group.AwaitEventWithAction(messages, types.ParentID(parent.ID), "process") + message, err := group.AwaitEventWithAction(messages, metadata.ParentID(parent.ID), "process") if err != ErrTimeout { t.Error(err) } - message.Next() + message.Ack() } // TestEventConsumer tests if events get consumed @@ -270,7 +271,7 @@ func TestEventConsumer(t *testing.T) { select { case event := <-events: - event.Next() + event.Ack() case <-ctx.Done(): t.Error("no message was consumed within the deadline") } @@ -298,7 +299,7 @@ func TestCommandConsumer(t *testing.T) { select { case message := <-messages: - message.Next() + message.Ack() case <-ctx.Done(): t.Error("no message was consumed within the deadline") } @@ -429,7 +430,7 @@ func TestCommandTimestampPassed(t *testing.T) { }) group.HandleFunc(EventMessage, "event", func(message *Message, writer Writer) { - parent, has := types.ParentTimestampFromContext(message.Ctx) + parent, has := metadata.ParentTimestampFromContext(message.Ctx()) if !has { t.Error("timestamp is not set") } @@ -460,9 +461,9 @@ func TestMessageMarked(t *testing.T) { message := types.NewMessage("testing", 1, nil, nil) message.Reset() go func() { - message.Next() + message.Ack() }() - message.Await() + message.Finally() } // TestNewConsumer tests if able to create a new consumer diff --git a/internal/types/metadata.go b/internal/metadata/context.go similarity index 92% rename from internal/types/metadata.go rename to internal/metadata/context.go index a2cda1d..f6d0ba1 100644 --- a/internal/types/metadata.go +++ b/internal/metadata/context.go @@ -1,4 +1,4 @@ -package types +package metadata import ( "context" @@ -35,14 +35,14 @@ func HeaderFromContext(ctx context.Context) (header Header, ok bool) { // NewRetriesContext creates a new context with Retries attached. If used // NewRetriesContext will overwrite any previously-appended -func NewRetriesContext(ctx context.Context, retries Retries) context.Context { +func NewRetriesContext(ctx context.Context, retries Header) context.Context { return context.WithValue(ctx, CtxRetries, retries) } // RetriesFromContext returns the Retries in ctx if it exists. // The returned Retries should not be modified. Writing to it may cause races. Modification should be made to copies of the returned Header. -func RetriesFromContext(ctx context.Context) (retries Retries, ok bool) { - retries, ok = ctx.Value(CtxRetries).(Retries) +func RetriesFromContext(ctx context.Context) (retries Header, ok bool) { + retries, ok = ctx.Value(CtxRetries).(Header) return } diff --git a/internal/types/headers.go b/internal/metadata/headers.go similarity index 97% rename from internal/types/headers.go rename to internal/metadata/headers.go index 030f9ad..6d853ea 100644 --- a/internal/types/headers.go +++ b/internal/metadata/headers.go @@ -1,4 +1,4 @@ -package types +package metadata import ( "strings" diff --git a/internal/types/main.go b/internal/metadata/main.go similarity index 95% rename from internal/types/main.go rename to internal/metadata/main.go index 8e6bd17..dd725cd 100644 --- a/internal/types/main.go +++ b/internal/metadata/main.go @@ -1,4 +1,4 @@ -package types +package metadata // CtxKey type type CtxKey string diff --git a/internal/types/codec.go b/internal/options/codec.go similarity index 98% rename from internal/types/codec.go rename to internal/options/codec.go index 34d43db..f22a0ed 100644 --- a/internal/types/codec.go +++ b/internal/options/codec.go @@ -1,6 +1,8 @@ -package types +package options -import "encoding/json" +import ( + "encoding/json" +) // Codec Codec defines the interface commander uses to encode and decode messages. // Note that implementations of this interface must be thread safe; a Codec's methods can be called from concurrent goroutines. diff --git a/internal/types/options.go b/internal/options/main.go similarity index 72% rename from internal/types/options.go rename to internal/options/main.go index 27bc8a9..d7f2230 100644 --- a/internal/types/options.go +++ b/internal/options/main.go @@ -1,6 +1,10 @@ -package types +package options -import "time" +import ( + "time" + + "github.com/jeroenrinzema/commander/internal/types" +) const ( // DefaultRetries represents the default amount of retry attempts @@ -54,28 +58,28 @@ type GroupOptions struct { Timeout time.Duration Codec Codec Retries int8 - Topics []Topic + Topics []types.Topic } -// NewHandleOptions applies the given serve options to construct a new handle options definition -func NewHandleOptions(options []HandleOption) (result *HandleOptions) { +// NewHandlerOptions applies the given serve options to construct a new handle options definition +func NewHandlerOptions(options []HandlerOption) (result *HandlerOptions) { // TODO: define default options - result = &HandleOptions{} + result = &HandlerOptions{} for _, option := range options { option.Apply(result) } return result } -// HandleOption sets options such as codec interfaces and timeouts -type HandleOption interface { - Apply(*HandleOptions) +// HandlerOption sets options such as codec interfaces and timeouts +type HandlerOption interface { + Apply(*HandlerOptions) } -// HandleOptions represent the available set of handle options -type HandleOptions struct { +// HandlerOptions represent the available set of handle options +type HandlerOptions struct { Action string - MessageType MessageType + MessageType types.MessageType Schema func() interface{} - Callback Handle + Callback types.HandlerFunc } diff --git a/internal/options/topic.go b/internal/options/topic.go new file mode 100644 index 0000000..19d1960 --- /dev/null +++ b/internal/options/topic.go @@ -0,0 +1,23 @@ +package options + +import "github.com/jeroenrinzema/commander/internal/types" + +// NewTopic constructs a new commander topic for the given name, type, mode and dialect. +// If no topic mode is defined is the default mode (consume|produce) assigned to the topic. +func NewTopic(name string, dialect types.Dialect, t types.MessageType, m types.TopicMode) GroupOption { + if m == 0 { + m = types.DefaultMode + } + + return &topic{ + Topic: types.NewTopic(name, dialect, t, m), + } +} + +type topic struct { + types.Topic +} + +func (option *topic) Apply(options *GroupOptions) { + options.Topics = append(options.Topics, option.Topic) +} diff --git a/internal/types/consumer.go b/internal/types/consumer.go index bbc33e3..f2e1c65 100644 --- a/internal/types/consumer.go +++ b/internal/types/consumer.go @@ -6,7 +6,7 @@ type Consumer interface { // messages consumed by the consumer of the given topic. This method // will return a message channel and a close function. // Once a message is successfully processed should the next message be called. - Subscribe(...Topic) (subscription <-chan *Message, err error) + Subscribe(topics ...Topic) (subscription <-chan *Message, err error) // Unsubscribe unsubscribes the given channel subscription from the given topic. // A boolean is returned that represents if the channel successfully got unsubscribed. diff --git a/internal/types/dialect.go b/internal/types/dialect.go index f9bf405..831fb41 100644 --- a/internal/types/dialect.go +++ b/internal/types/dialect.go @@ -3,9 +3,6 @@ package types // Dialect represents a commander dialect. // A dialect is responsible for the consumption/production of the targeted protocol. type Dialect interface { - // Assigned notifies a dialect about the assignment of the given topic - Assigned(topic Topic) - // Consumer returns the dialect consumer Consumer() Consumer @@ -17,9 +14,8 @@ type Dialect interface { // The user should implement the health check Healthy() bool - // Open notifies a dialect to open the dialect. - // No further topic assignments should be made. - Open() error + // Opens the given dialect to start accepting incoming and outgoing connections. + Open(topics []Topic) error // Close awaits till the consumer(s) and producer(s) of the given dialect are closed. // If an error is returned is the closing aborted and the error returned to the user. diff --git a/internal/types/group.go b/internal/types/group.go index 5b33536..4204c1c 100644 --- a/internal/types/group.go +++ b/internal/types/group.go @@ -6,8 +6,8 @@ type Close func() // Next indicates that the next message could be called type Next func() -// Handle message handle message, writer implementation -type Handle func(*Message, Writer) +// HandlerFunc message handle message, writer implementation +type HandlerFunc func(*Message, Writer) // Handler interface handle wrapper type Handler interface { diff --git a/internal/types/message.go b/internal/types/message.go index fa5110c..1364904 100644 --- a/internal/types/message.go +++ b/internal/types/message.go @@ -2,13 +2,36 @@ package types import ( "context" + "errors" "strconv" "sync" "time" "github.com/gofrs/uuid" + "github.com/jeroenrinzema/commander/internal/metadata" ) +var ( + // ErrNegativeAcknowledgement is a error representing a negative message acknowledgement + ErrNegativeAcknowledgement = errors.New("negative acknowledgement") +) + +// Resolved represents a message ack/nack status +type Resolved int + +// available Resolved types +const ( + UnkownResolvedStatus Resolved = iota + ResolvedAck + ResolvedNack +) + +var closed = make(chan struct{}) + +func init() { + close(closed) +} + // Version message version type Version int8 @@ -78,35 +101,38 @@ func NewMessage(action string, version int8, key []byte, data []byte) *Message { } return &Message{ - Ctx: context.Background(), - ID: id, - Action: action, - Version: Version(version), - Key: key, - Data: data, - async: make(chan struct{}, 0), + ID: id, + Action: action, + Version: Version(version), + Key: key, + Data: data, + ack: make(chan struct{}, 0), + nack: make(chan struct{}, 0), + response: UnkownResolvedStatus, + Status: StatusOK, + Timestamp: time.Now(), + ctx: context.Background(), } } // Message representation type Message struct { - ID string `json:"id"` - Status StatusCode `json:"status"` - Topic Topic `json:"topic"` - Action string `json:"action"` - Version Version `json:"version"` - Data []byte `json:"data"` - Key []byte `json:"key"` - EOS EOS `json:"eos"` - Timestamp time.Time `json:"timestamp"` - Ctx context.Context `json:"-"` - - // NOTE: include message topic origin? - schema interface{} - async chan struct{} - result error - once sync.Once - mutex sync.RWMutex + ID string `json:"id"` + Status StatusCode `json:"status"` + Topic Topic `json:"topic"` + Action string `json:"action"` + Version Version `json:"version"` + Data []byte `json:"data"` + Key []byte `json:"key"` + EOS EOS `json:"eos"` + Timestamp time.Time `json:"timestamp"` + + ctx context.Context + schema interface{} + ack chan struct{} + nack chan struct{} + response Resolved + mutex sync.RWMutex } // Schema returns the decoded message schema @@ -128,29 +154,19 @@ func (message *Message) NewError(action string, status StatusCode, err error) *M } // NewMessage construct a new event message with the given message as parent -func (message *Message) NewMessage(action string, version Version, key Key, data []byte) *Message { - child := &Message{} - child.Ctx = context.Background() - - child.Ctx = NewParentIDContext(child.Ctx, ParentID(message.ID)) - child.Ctx = NewParentTimestampContext(child.Ctx, ParentTimestamp(message.Timestamp)) - - child.ID = uuid.Must(uuid.NewV4()).String() - child.Action = action - child.Status = StatusOK - child.Data = data - child.Timestamp = time.Now() - child.Version = message.Version - child.Key = key - - if child.Key == nil { - child.Key = message.Key +func (message *Message) NewMessage(action string, version Version, key metadata.Key, data []byte) *Message { + if key == nil { + key = message.Key } if version == NullVersion { - child.Version = message.Version + version = message.Version } + child := NewMessage(action, int8(version), key, data) + child.ctx = metadata.NewParentIDContext(child.ctx, metadata.ParentID(message.ID)) + child.ctx = metadata.NewParentTimestampContext(child.ctx, metadata.ParentTimestamp(message.Timestamp)) + return child } @@ -163,51 +179,98 @@ func (message *Message) Reset() { message.mutex.Lock() defer message.mutex.Unlock() - message.once = sync.Once{} - message.async = make(chan struct{}, 0) + message.ack = make(chan struct{}, 0) + message.nack = make(chan struct{}, 0) + message.response = UnkownResolvedStatus + return } -// Retry mark the message as resolved and attempt to retry the message -func (message *Message) Retry(err error) { +// Ack mark the message as acknowledged +func (message *Message) Ack() bool { if message == nil { - return + return false } - message.resolve(err) -} + message.mutex.Lock() + defer message.mutex.Unlock() -// Next mark the message as resolved -func (message *Message) Next() { - if message == nil { - return + if message.response == ResolvedNack { + return false + } + + message.response = ResolvedAck + + if message.ack == nil { + message.ack = closed + return true } - message.resolve(nil) + close(message.ack) + return true } -func (message *Message) resolve(err error) { +// Acked returns a channel thet get's closed once a acknowledged signal got sent +func (message *Message) Acked() <-chan struct{} { + return message.ack +} + +// Nack send a negative acknowledged +func (message *Message) Nack() bool { if message == nil { - return + return false } - message.mutex.RLock() - defer message.mutex.RUnlock() + message.mutex.Lock() + defer message.mutex.Unlock() + + if message.response == ResolvedAck { + return false + } + + message.response = ResolvedNack + + if message.nack == nil { + message.nack = closed + return true + } + + close(message.nack) + return true +} - message.once.Do(func() { - message.result = err - close(message.async) - }) +// Nacked returns a channel that get's closed once a negative acknowledged signal got sent +func (message *Message) Nacked() <-chan struct{} { + return message.nack } -// Await await untill the message is resolved -func (message *Message) Await() error { +// Finally is returned once the message is resolved. +// A ErrNegativeAcknowledgement error is returned if the message got negative acknowledged. +func (message *Message) Finally() error { if message == nil { return nil } + select { + case <-message.Acked(): + return nil + case <-message.Nacked(): + return ErrNegativeAcknowledgement + } +} + +// Ctx returns the message context. +// This method could safely be called concurrently. +func (message *Message) Ctx() context.Context { message.mutex.RLock() defer message.mutex.RUnlock() - <-message.async - return message.result + return message.ctx +} + +// NewCtx updates the message context. +// This method could safely be called concurrently. +func (message *Message) NewCtx(ctx context.Context) { + message.mutex.Lock() + defer message.mutex.Unlock() + message.ctx = ctx } diff --git a/internal/types/topic.go b/internal/types/topic.go index e1a9976..2824e6a 100644 --- a/internal/types/topic.go +++ b/internal/types/topic.go @@ -12,24 +12,6 @@ const ( DefaultMode = ConsumeMode | ProduceMode ) -// NewTopic constructs a new commander topic for the given name, type, mode and dialect. -// If no topic mode is defined is the default mode (consume|produce) assigned to the topic. -func NewTopic(name string, dialect Dialect, t MessageType, m TopicMode) Topic { - if m == 0 { - m = DefaultMode - } - - topic := &topic{ - name: name, - dialect: dialect, - messages: t, - mode: m, - } - - dialect.Assigned(topic) - return topic -} - // Topic represents a subject for a dialect including it's // consumer/producer mode. type Topic interface { @@ -43,8 +25,19 @@ type Topic interface { HasMode(TopicMode) bool // Name returns the topic name Name() string - // Apply applies the topic to the given group configuration - Apply(*GroupOptions) +} + +// NewTopic constructs a new commander topic for the given name, type, mode and dialect. +// If no topic mode is defined is the default mode (consume|produce) assigned to the topic. +func NewTopic(name string, dialect Dialect, t MessageType, m TopicMode) Topic { + topic := &topic{ + name: name, + dialect: dialect, + messages: t, + mode: m, + } + + return topic } // Topic interface implementation @@ -55,10 +48,6 @@ type topic struct { mode TopicMode } -func (topic *topic) Apply(options *GroupOptions) { - options.Topics = append(options.Topics, topic) -} - func (topic *topic) Dialect() Dialect { return topic.dialect } diff --git a/main.go b/main.go index 17a59fe..50fd319 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,8 @@ package commander import ( "errors" - "github.com/jeroenrinzema/commander/middleware" "github.com/jeroenrinzema/commander/internal/types" + "github.com/jeroenrinzema/commander/middleware" ) const ( @@ -27,32 +27,18 @@ var ( // NewClient constructs a new commander client. // A client is needed to control a collection of groups. func NewClient(groups ...*Group) (*Client, error) { + middleware := middleware.NewClient() client := &Client{ - Groups: groups, - Middleware: middleware.NewClient(), + UseImpl: middleware, + Groups: groups, } - topics := []types.Topic{} - dialects := []types.Dialect{} - - for _, group := range groups { - group.Middleware = client.Middleware - topics = append(topics, group.Topics...) - } - -topic: - for _, topic := range topics { - for _, dialect := range dialects { - if topic.Dialect() == dialect { - continue topic - } - } - - dialects = append(dialects, topic.Dialect()) - } + appendMiddleware(middleware, groups) + topics := pullTopicsFromGroups(groups) + dialects := groupTopicsByDialect(topics) - for _, dialect := range dialects { - err := dialect.Open() + for dialect, topics := range dialects { + err := dialect.Open(topics) if err != nil { return nil, err } @@ -63,8 +49,8 @@ topic: // Client manages the consumers, producers and groups. type Client struct { - Middleware *middleware.Client - Groups []*Group + middleware.UseImpl + Groups []*Group } // Close closes the consumer and producer @@ -84,3 +70,32 @@ func (client *Client) Close() error { return nil } + +func pullTopicsFromGroups(groups []*Group) []types.Topic { + returned := []types.Topic{} + for _, group := range groups { + returned = append(returned, group.Topics...) + } + + return returned +} + +func appendMiddleware(middleware middleware.UseImpl, groups []*Group) { + for _, group := range groups { + group.Middleware = middleware + } +} + +func groupTopicsByDialect(topics []types.Topic) map[types.Dialect][]types.Topic { + returned := map[types.Dialect][]types.Topic{} + for _, topic := range topics { + _, has := returned[topic.Dialect()] + if !has { + returned[topic.Dialect()] = []types.Topic{} + } + + returned[topic.Dialect()] = append(returned[topic.Dialect()], topic) + } + + return returned +} diff --git a/middleware/main.go b/middleware/main.go index d6ec9fb..b54ce37 100644 --- a/middleware/main.go +++ b/middleware/main.go @@ -1,77 +1,92 @@ package middleware import ( - "context" "sync" + + "github.com/jeroenrinzema/commander/internal/types" ) -// Controller middleware controller -type Controller interface { - Use(*Client) +// BeforeConsumeHandlerFunc represents the function method called and returned by a middleware client +type BeforeConsumeHandlerFunc = types.HandlerFunc + +// BeforeProduceHandlerFunc represents the function method called and returned by a middleware client +type BeforeProduceHandlerFunc = func(*types.Message) + +// ConsumeController middleware controller +type ConsumeController interface { + BeforeConsume(types.HandlerFunc) types.HandlerFunc } -// Handle represents a middleware handle -type Handle func(ctx context.Context, message interface{}) +// ProduceController middleware controller +type ProduceController interface { + BeforeProduce(*types.Message) *types.Message +} -// Subscribe represents a subscribe handler -type Subscribe func(event interface{}, handle Handle) +// Client middleware interface +type Client interface { + WrapBeforeConsume(BeforeConsumeHandlerFunc) BeforeConsumeHandlerFunc + WrapBeforeProduce(BeforeProduceHandlerFunc) BeforeProduceHandlerFunc +} -// Collection holds a collection of middleware event subscriptions -type Collection struct { - subscriptions []Handle - mutex sync.Mutex +// UseImpl exposed usage interface. +// The interface could not be called Use due to type reference issues. +type UseImpl interface { + Use(interface{}) } // NewClient constructs a new middleware client -func NewClient() *Client { - client := &Client{ - events: make(map[interface{}]*Collection), +func NewClient() UseImpl { + client := &client{ + consume: []ConsumeController{}, + produce: []ProduceController{}, } return client } -// Client handles all middleware event subscriptions. -// If a event is emitted are the subscribed middleware methods called and awaited. -type Client struct { - events map[interface{}]*Collection - mutex sync.Mutex +type client struct { + consume []ConsumeController + produce []ProduceController + + mutex sync.RWMutex } -// Emit calls all the subscribed middleware handles on the given event type. -// Each handle is called and awaited in order for it to manipulate or process a response. -// If a handle returns a error message is the manipulated message ignored. -func (client *Client) Emit(ctx context.Context, event interface{}, message interface{}) { +// Use calles the given middleware controller to initialize the middleware +func (client *client) Use(value interface{}) { client.mutex.Lock() defer client.mutex.Unlock() - if client.events[event] == nil { - return + if controller, ok := value.(ConsumeController); ok { + client.consume = append(client.consume, controller) } - client.events[event].mutex.Lock() - defer client.events[event].mutex.Unlock() - - for _, handle := range client.events[event].subscriptions { - handle(ctx, message) + if controller, ok := value.(ProduceController); ok { + client.produce = append(client.produce, controller) } } -// Subscribe creates a new middleware subscription for the given event type. -func (client *Client) Subscribe(event interface{}, handle Handle) { - if client.events[event] == nil { - client.mutex.Lock() - client.events[event] = &Collection{subscriptions: []Handle{}} - client.mutex.Unlock() +// WrapBeforeConsume executes defined consume middleware in chronological order. +// A handle executable handler is returned once all middleware is wrapped. +func (client *client) WrapBeforeConsume(h types.HandlerFunc) types.HandlerFunc { + if len(client.consume) < 1 { + return h } - client.events[event].mutex.Lock() - defer client.events[event].mutex.Unlock() + wrapped := h + + // loop in reverse to preserve middleware order + for i := len(client.consume) - 1; i >= 0; i-- { + wrapped = client.consume[i].BeforeConsume(wrapped) + } - client.events[event].subscriptions = append(client.events[event].subscriptions, handle) + return wrapped } -// Use calles the given middleware controller to initialize the middleware -func (client *Client) Use(controller Controller) { - controller.Use(client) +// WrapBeforeProduce executes defined produce middleware in chronological order. +// A handle executable handler is returned once all middleware is wrapped. +func (client *client) WrapBeforeProduce(m *types.Message) { + // loop in reverse to preserve middleware order + for i := len(client.produce) - 1; i >= 0; i-- { + client.produce[i].BeforeProduce(m) + } } diff --git a/middleware/main_test.go b/middleware/main_test.go deleted file mode 100644 index d312295..0000000 --- a/middleware/main_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package middleware - -import ( - "context" - "testing" - "time" -) - -// EventType used for testing purposes -type EventType string - -// Available event types used for testing -const ( - Before = EventType("before") - After = EventType("after") -) - -// TestEmittingMessage tests if able to emit a message -func TestEmittingMessage(t *testing.T) { - sink := make(chan bool, 1) - client := NewClient() - - timeout, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) - defer cancel() - - client.Subscribe(Before, func(ctx context.Context, message interface{}) { - sink <- true - }) - - client.Emit(context.Background(), Before, nil) - - select { - case <-timeout.Done(): - t.Fatal("Timeout reached") - case <-sink: - } -} diff --git a/middleware/recover/main.go b/middleware/recover/main.go new file mode 100644 index 0000000..7a1db23 --- /dev/null +++ b/middleware/recover/main.go @@ -0,0 +1,18 @@ +package recover + +import "github.com/jeroenrinzema/commander/internal/types" + +type Controller struct{} + +func (controller *Controller) Middleware(next types.HandlerFunc) types.HandlerFunc { + return func(message *types.Message, writer types.Writer) { + defer func() { + err := recover() + if err != nil { + // TODO: log recover err + } + }() + + next(message, writer) + } +} diff --git a/middleware/throttle/main.go b/middleware/throttle/main.go new file mode 100644 index 0000000..79f3afc --- /dev/null +++ b/middleware/throttle/main.go @@ -0,0 +1,30 @@ +package throttle + +import ( + "time" + + "github.com/jeroenrinzema/commander/internal/types" +) + +// Throttle provides a middleware that limits the amount of messages processed per unit of time. +// This may be done e.g. to prevent excessive load caused by running a handler on a long queue of unprocessed messages. +type Throttle struct { + throttle <-chan time.Time +} + +// NewThrottle creates a new Throttle middleware. +// Example duration and count: NewThrottle(10, time.Second) for 10 messages per second +func NewThrottle(count int64, duration time.Duration) *Throttle { + return &Throttle{time.Tick(duration / time.Duration(count))} +} + +func (t Throttle) Middleware(h types.HandlerFunc) types.HandlerFunc { + return func(message *types.Message, writer types.Writer) { + select { + case <-t.throttle: + // throttle is shared by multiple handlers, which will wait for their "tick" + } + + h(message, writer) + } +} diff --git a/middleware/timeout/main.go b/middleware/timeout/main.go new file mode 100644 index 0000000..64298b3 --- /dev/null +++ b/middleware/timeout/main.go @@ -0,0 +1,25 @@ +package timeout + +import ( + "context" + "time" + + "github.com/jeroenrinzema/commander/internal/types" +) + +// func New() middleware.Controller { +// } + +type Controller struct { +} + +// Middleware ... +func (c *Controller) Middleware(next types.HandlerFunc) types.HandlerFunc { + return func(message *types.Message, writer types.Writer) { + ctx, cancel := context.WithTimeout(message.Ctx(), time.Second) + defer cancel() + + message.NewCtx(ctx) + next(message, writer) + } +} diff --git a/middleware/zipkin/main.go b/middleware/zipkin/main.go index 72c7532..c8d010b 100644 --- a/middleware/zipkin/main.go +++ b/middleware/zipkin/main.go @@ -1,9 +1,7 @@ package zipkin import ( - "context" - - "github.com/jeroenrinzema/commander" + "github.com/jeroenrinzema/commander/internal/types" "github.com/jeroenrinzema/commander/middleware" "github.com/jeroenrinzema/commander/middleware/zipkin/metadata" zipkin "github.com/openzipkin/zipkin-go" @@ -57,26 +55,31 @@ type Zipkin struct { Config Config } -// Use let the current instance use the given middleware client -func (service *Zipkin) Use(client *middleware.Client) { - client.Subscribe(commander.BeforeActionConsumption, service.BeforeConsume) - client.Subscribe(commander.AfterActionConsumption, service.AfterConsume) - client.Subscribe(commander.BeforePublish, service.BeforePublish) - client.Subscribe(commander.AfterPublish, service.AfterPublish) +// BeforeConsume middleware controller +func (controller *Zipkin) BeforeConsume(next middleware.BeforeConsumeHandlerFunc) middleware.BeforeConsumeHandlerFunc { + return func(message *types.Message, writer types.Writer) { + controller.NewConsumeSpan(message) + defer controller.AfterConsumeSpan(message) + next(message, writer) + } } -// Close closes the Zipkin reporter -func (service *Zipkin) Close() error { - return service.Reporter.Close() +// BeforeProduce middleware controller +func (controller *Zipkin) BeforeProduce(next middleware.BeforeProduceHandlerFunc) middleware.BeforeProduceHandlerFunc { + return func(message *types.Message) { + controller.NewProduceSpan(message) + defer controller.AfterPublishSpan(message) + next(message) + } } -// BeforeConsume starts a new span and stores it in the message context -func (service *Zipkin) BeforeConsume(ctx context.Context, event interface{}) { - message, ok := event.(*commander.Message) - if !ok { - return - } +// Close closes the Zipkin reporter +func (controller *Zipkin) Close() error { + return controller.Reporter.Close() +} +// NewConsumeSpan starts a new span and stores it in the message context +func (controller *Zipkin) NewConsumeSpan(message *types.Message) { options := []zipkin.SpanOption{ zipkin.Kind(model.Consumer), } @@ -87,16 +90,17 @@ func (service *Zipkin) BeforeConsume(ctx context.Context, event interface{}) { } name := "commander.consume." + message.Action - span := service.Tracer.StartSpan(name, options...) - ctx = metadata.NewSpanConsumeContext(ctx, span) + span := controller.Tracer.StartSpan(name, options...) + + message.NewCtx(metadata.NewSpanConsumeContext(message.Ctx(), span)) span.Tag(ActionTag, message.Action) span.Tag(VersionTag, message.Version.String()) } -// AfterConsume finishes the stored span in the message context -func (service *Zipkin) AfterConsume(ctx context.Context, event interface{}) { - span, has := metadata.SpanConsumeFromContext(ctx) +// AfterConsumeSpan finishes the stored span in the message context +func (controller *Zipkin) AfterConsumeSpan(message *types.Message) { + span, has := metadata.SpanConsumeFromContext(message.Ctx()) if !has { return } @@ -104,30 +108,25 @@ func (service *Zipkin) AfterConsume(ctx context.Context, event interface{}) { span.Finish() } -// BeforePublish prepares the given message span headers -func (service *Zipkin) BeforePublish(ctx context.Context, event interface{}) { - message, ok := event.(*commander.Message) - if !ok { - return - } - - parent, has := metadata.SpanConsumeFromContext(ctx) +// NewProduceSpan prepares the given message span headers +func (controller *Zipkin) NewProduceSpan(message *types.Message) { + parent, has := metadata.SpanConsumeFromContext(message.Ctx()) if !has { return } - span := service.Tracer.StartSpan("commander.produce", zipkin.Kind(model.Consumer), zipkin.Parent(parent.Context())) + span := controller.Tracer.StartSpan("commander.produce", zipkin.Kind(model.Consumer), zipkin.Parent(parent.Context())) span.Tag(ActionTag, message.Action) span.Tag(VersionTag, message.Version.String()) - ctx = metadata.NewSpanProduceContext(ctx, span) - ctx = metadata.AppendMessageHeaders(ctx, span.Context()) + message.NewCtx(metadata.NewSpanProduceContext(message.Ctx(), span)) + message.NewCtx(metadata.AppendMessageHeaders(message.Ctx(), span.Context())) } -// AfterPublish closes the producing span -func (service *Zipkin) AfterPublish(ctx context.Context, event interface{}) { - span, has := metadata.SpanProduceFromContext(ctx) +// AfterPublishSpan closes the producing span +func (controller *Zipkin) AfterPublishSpan(message *types.Message) { + span, has := metadata.SpanProduceFromContext(message.Ctx()) if !has { return } diff --git a/middleware/zipkin/metadata/headers.go b/middleware/zipkin/metadata/headers.go index b18cb10..6c24ec4 100644 --- a/middleware/zipkin/metadata/headers.go +++ b/middleware/zipkin/metadata/headers.go @@ -5,15 +5,15 @@ import ( "strconv" "github.com/jeroenrinzema/commander" - - "github.com/jeroenrinzema/commander/internal/types" + + "github.com/jeroenrinzema/commander/internal/metadata" "github.com/openzipkin/zipkin-go/model" ) // ExtractContextFromMessageHeaders attempts to extracts the span context from the message headers. func ExtractContextFromMessageHeaders(message *commander.Message) (span model.SpanContext, ok bool) { - var headers types.Header - headers, ok = types.HeaderFromContext(message.Ctx) + var headers metadata.Header + headers, ok = metadata.HeaderFromContext(message.Ctx()) if !ok { return span, ok } @@ -63,12 +63,12 @@ func AppendMessageHeaders(ctx context.Context, span model.SpanContext) context.C parent = span.ParentID.String() } - headers := types.Header{ + headers := metadata.Header{ HeaderTraceID: []string{span.TraceID.String()}, HeaderSpanID: []string{span.ID.String()}, HeaderParentSpanID: []string{parent}, HeaderSampled: []string{sampled}, } - return types.AppendToHeaderContext(ctx, headers) + return metadata.AppendToHeaderContext(ctx, headers) } diff --git a/options.go b/options.go index 6cefe09..aec18fe 100644 --- a/options.go +++ b/options.go @@ -3,6 +3,7 @@ package commander import ( "time" + "github.com/jeroenrinzema/commander/internal/options" "github.com/jeroenrinzema/commander/internal/types" ) @@ -10,12 +11,12 @@ type timeout struct { duration time.Duration } -func (t *timeout) Apply(options *types.GroupOptions) { +func (t *timeout) Apply(options *options.GroupOptions) { options.Timeout = t.duration } // WithAwaitTimeout returns a GroupOption that configures the timeout period for the given group -func WithAwaitTimeout(d time.Duration) types.GroupOption { +func WithAwaitTimeout(d time.Duration) options.GroupOption { return &timeout{d} } @@ -23,12 +24,12 @@ type action struct { name string } -func (a *action) Apply(options *types.HandleOptions) { +func (a *action) Apply(options *options.HandlerOptions) { options.Action = a.name } // WithAction returns a HandleOptions that configures the action handle -func WithAction(n string) types.HandleOption { +func WithAction(n string) options.HandlerOption { return &action{n} } @@ -36,25 +37,25 @@ type messageType struct { value types.MessageType } -func (t *messageType) Apply(options *types.HandleOptions) { +func (t *messageType) Apply(options *options.HandlerOptions) { options.MessageType = t.value } // WithMessageType returns a HandleOptions that configures the message type handle -func WithMessageType(t types.MessageType) types.HandleOption { +func WithMessageType(t types.MessageType) options.HandlerOption { return &messageType{t} } type callback struct { - handle types.Handle + handle types.HandlerFunc } -func (c *callback) Apply(options *types.HandleOptions) { +func (c *callback) Apply(options *options.HandlerOptions) { options.Callback = c.handle } // WithCallback returns a HandleOptions that configures the callback method for a given handle -func WithCallback(h types.Handle) types.HandleOption { +func WithCallback(h types.HandlerFunc) options.HandlerOption { return &callback{h} } @@ -62,11 +63,11 @@ type schema struct { handle func() interface{} } -func (s *schema) Apply(options *types.HandleOptions) { +func (s *schema) Apply(options *options.HandlerOptions) { options.Schema = s.handle } // WithMessageSchema returns a HandleOptions that configures the message schema for a handle -func WithMessageSchema(f func() interface{}) types.HandleOption { +func WithMessageSchema(f func() interface{}) options.HandlerOption { return &schema{f} } diff --git a/types.go b/types.go index 04274c5..9307d4d 100644 --- a/types.go +++ b/types.go @@ -1,6 +1,9 @@ package commander -import "github.com/jeroenrinzema/commander/internal/types" +import ( + "github.com/jeroenrinzema/commander/internal/options" + "github.com/jeroenrinzema/commander/internal/types" +) // To avoid circular dependencies are some types/interfaces/structs moved to a seperate package (types). // In order to still be able to use the types by simply importing commander are the types imported and extended in commander. @@ -39,7 +42,7 @@ const ( // NewTopic constructs a new commander topic for the given name, type, mode and dialect. // If no topic mode is defined is the default mode (consume|produce) assigned to the topic. -var NewTopic = types.NewTopic +var NewTopic = options.NewTopic // Topic contains information of a kafka topic type Topic = types.Topic @@ -47,5 +50,5 @@ type Topic = types.Topic // NewMessage types.NewMessage alias var NewMessage = types.NewMessage -// WithJSONCodec types.WithJSONCodec alias -var WithJSONCodec = types.WithJSONCodec +// WithJSONCodec options.WithJSONCodec alias +var WithJSONCodec = options.WithJSONCodec diff --git a/writer.go b/writer.go index 4f2f0d9..3d851cb 100644 --- a/writer.go +++ b/writer.go @@ -1,6 +1,7 @@ package commander import ( + "github.com/jeroenrinzema/commander/internal/metadata" "github.com/jeroenrinzema/commander/internal/types" ) @@ -26,7 +27,7 @@ type writer struct { // NewMessage constructs a new message or a child of the parent. func (writer *writer) NewMessage(action string, version int8, key []byte, data []byte) *Message { if writer.parent != nil { - return writer.parent.NewMessage(action, types.Version(version), types.Key(key), data) + return writer.parent.NewMessage(action, types.Version(version), metadata.Key(key), data) } return types.NewMessage(action, version, key, data) diff --git a/writer_test.go b/writer_test.go index 83b7b2e..75c460f 100644 --- a/writer_test.go +++ b/writer_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/jeroenrinzema/commander/internal/types" + "github.com/jeroenrinzema/commander/internal/metadata" ) // TestNewResponseWriter tests if able to construct a new resoponse writer @@ -53,7 +53,7 @@ func TestWriterProduceCommand(t *testing.T) { t.Error("unexpected stream") } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") } @@ -93,7 +93,7 @@ func TestWriterProduceCommandStream(t *testing.T) { t.Error("unexpected EOS") } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") } @@ -137,7 +137,7 @@ func TestWriterProduceEvent(t *testing.T) { t.Error("unexpected stream") } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") } @@ -178,12 +178,12 @@ func TestWriterProduceEventStream(t *testing.T) { t.Error("unexpected EOS") } - id, _ := types.ParentIDFromContext(message.Ctx) - if id != types.ParentID(parent.ID) { + id, _ := metadata.ParentIDFromContext(message.Ctx()) + if id != metadata.ParentID(parent.ID) { t.Error("The event parent does not match the parent id:", id, parent.ID) } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") } @@ -223,12 +223,12 @@ func TestWriterProduceErrorEvent(t *testing.T) { t.Error("unexpected stream") } - id, _ := types.ParentIDFromContext(message.Ctx) - if id != types.ParentID(parent.ID) { + id, _ := metadata.ParentIDFromContext(message.Ctx()) + if id != metadata.ParentID(parent.ID) { t.Error("The event parent does not match the parent id:", id, parent.ID) } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") } @@ -268,12 +268,12 @@ func TestWriterProduceErrorEventStream(t *testing.T) { t.Error("unexpected EOS") } - id, _ := types.ParentIDFromContext(message.Ctx) - if id != types.ParentID(parent.ID) { + id, _ := metadata.ParentIDFromContext(message.Ctx()) + if id != metadata.ParentID(parent.ID) { t.Error("The event parent does not match the parent id:", id, parent.ID) } - message.Next() + message.Ack() case <-ctx.Done(): t.Error("the events handle was not called within the deadline") }