From 78082aa3d7a259db5b9de7ffe7c23433561f7798 Mon Sep 17 00:00:00 2001 From: bounoable Date: Wed, 12 Feb 2025 15:35:33 +0100 Subject: [PATCH] refactor(event/handler)!: change merging behavior of `Startup()` option --- event/handler/handler.go | 14 ++++++-------- event/handler/handler_test.go | 27 ++++++++++++++++++--------- event/query/query.go | 6 +++--- go.work.sum | 10 ++++++++++ 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/event/handler/handler.go b/event/handler/handler.go index 495728b2..ff685968 100644 --- a/event/handler/handler.go +++ b/event/handler/handler.go @@ -62,15 +62,15 @@ type Option func(*Handler) // events are fetched from the store. The returned [Option] can be used when // creating a new [Handler]. // -// If [query.Option]s are provided, they will be merged with the default query -// using [query.Merge]. If you want to _replace_ the default query, use the -// [StartupQuery] option instead of providing [query.Option]s to [Startup]. +// If [query.Option]s are provided, they will be used to construct a new query +// that replaces the default query. If you want to modify the default query +// instead, use the [StartupQuery] option. func Startup(store event.Store, opts ...query.Option) Option { return func(h *Handler) { h.startupStore = store if len(opts) > 0 { - StartupQuery(func(q event.Query) event.Query { - return query.Merge(q, query.New(opts...)) + StartupQuery(func(event.Query) event.Query { + return query.New(opts...) })(h) } } @@ -79,9 +79,7 @@ func Startup(store event.Store, opts ...query.Option) Option { // StartupQuery is a function that configures a [Handler]'s startup query. It // accepts a function that takes and returns an event.Query as its argument. The // provided function will be used by the [Handler] to modify the default query -// used when fetching events from the event store during startup. The resulting -// [Option] can be used when constructing a new [Handler], allowing -// customization of the startup behavior of the [Handler]. +// used when fetching events from the event store during startup. func StartupQuery(fn func(event.Query) event.Query) Option { return func(h *Handler) { h.startupQuery = fn diff --git a/event/handler/handler_test.go b/event/handler/handler_test.go index 5d65f89d..29279aa0 100644 --- a/event/handler/handler_test.go +++ b/event/handler/handler_test.go @@ -151,7 +151,7 @@ func TestStartupQuery(t *testing.T) { } } -func TestStartup_withQuery_merges_names(t *testing.T) { +func TestStartup_withQuery_replaces_names(t *testing.T) { bus := eventbus.New() store := eventstore.New() @@ -195,13 +195,13 @@ func TestStartup_withQuery_merges_names(t *testing.T) { }() select { - case <-time.After(time.Second): - t.Fatalf("foo event was not handled") + case <-time.After(50 * time.Millisecond): case <-fooHandled: + t.Fatalf("foo event was handled") } select { - case <-time.After(time.Second): + case <-time.After(50 * time.Millisecond): t.Fatalf("bar event was not handled #1") case evt := <-barHandled: if evt.ID() != testID { @@ -210,7 +210,7 @@ func TestStartup_withQuery_merges_names(t *testing.T) { } select { - case <-time.After(time.Second): + case <-time.After(50 * time.Millisecond): t.Fatalf("bar event was not handled #2") case evt := <-barHandled: if evt.ID() == testID { @@ -219,7 +219,7 @@ func TestStartup_withQuery_merges_names(t *testing.T) { } } -func TestStartup_withQuery_merges_ids(t *testing.T) { +func TestStartup_withQuery_replaces_ids(t *testing.T) { bus := eventbus.New() store := eventstore.New() @@ -243,6 +243,7 @@ func TestStartup_withQuery_merges_ids(t *testing.T) { context.Background(), event.New("foo", test.FooEventData{}).Any(), event.New("bar", test.BarEventData{}, event.ID(testID)).Any(), + event.New("bar", test.BarEventData{}).Any(), // Add another bar event without testID ); err != nil { t.Fatalf("Insert() failed with %q", err) } @@ -261,15 +262,23 @@ func TestStartup_withQuery_merges_ids(t *testing.T) { select { case <-time.After(50 * time.Millisecond): case <-fooHandled: - t.Fatalf("foo event was handled") + t.Fatalf("foo event was handled when it should have been filtered out") } select { - case <-time.After(time.Second): - t.Fatalf("bar event was not handled") + case <-time.After(50 * time.Millisecond): + t.Fatalf("bar event with matching ID was not handled") case evt := <-barHandled: if evt.ID() != testID { t.Fatalf("expected event ID %q; got %q", testID, evt.ID()) } } + + // Verify that the other bar event without testID is not handled + select { + case <-time.After(50 * time.Millisecond): + // This is the expected behavior - event without matching ID should not be handled + case <-barHandled: + t.Fatalf("bar event without matching ID was incorrectly handled") + } } diff --git a/event/query/query.go b/event/query/query.go index 14c4585a..2a904ca6 100644 --- a/event/query/query.go +++ b/event/query/query.go @@ -166,9 +166,9 @@ func SortByMulti(sorts ...event.SortOptions) Option { // SortByAggregate returns an Option that sorts the a Query by aggregates. // // Order of sortings is: -// 1. aggregateName (ascending) -// 2. aggregateID (ascending) -// 3. aggregateVersion (ascending) +// 1. aggregateName (ascending) +// 2. aggregateID (ascending) +// 3. aggregateVersion (ascending) func SortByAggregate() Option { return SortByMulti( event.SortOptions{Sort: event.SortAggregateName, Dir: event.SortAsc}, diff --git a/go.work.sum b/go.work.sum index 9135239c..d6c15a97 100644 --- a/go.work.sum +++ b/go.work.sum @@ -619,6 +619,7 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -740,6 +741,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -849,6 +852,7 @@ golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -891,6 +895,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= @@ -900,6 +906,7 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -908,6 +915,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1110,6 +1119,7 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=