modernice / goes

goes is an event-sourcing framework for Go.
https://goes.modernice.dev
Apache License 2.0
134 stars 12 forks source link

Does lookup.Remove remove all values are just a single value #169

Closed olpie101 closed 9 months ago

olpie101 commented 1 year ago

Does the remove method remove a single value or all values? If we use the following example for an event:

func (data SomeEvent) ProvideLookup(p lookup.Provider) {
    p.Remove(SomeEventLookup)
}

Does this remove the value for this event from the lookup or all values for the given lookup key. If it remove all values, is there a way to remove a single key from the lookup?

bounoable commented 1 year ago

It will remove the lookup value only for the specific aggregate of this event. This depends on the aggregate data of the event:

type SomeEvent struct {}

func (data SomeEvent) ProvideLookup(p lookup.Provider) {
    p.Remove(SomeEventLookup)
}

func example(id uuid.UUID) {
  // The lookup is for the specific aggregate with name "foo" and the provided id.
  evt := event.New("foobar", SomeEvent{}, event.Aggregate(id, "foo", 1))

  // The lookup is for the aggregate with name "" and uuid.Nil (global/singleton lookup)
  evt := event.New("foobar", SomeEvent{})

  // The lookup is for the aggregate with name "foo" and uuid.Nil (lookup is for _all_ "foo" aggregates)
  evt := event.New("foobar", SomeEvent{}, event.Aggregate(uuid.Nil, "foo", 1))

  // The lookup is for the aggregate with name "" and the provided id (lookup is for _all_ aggregates with the provided id)
  evt := event.New("foobar", SomeEvent{}, event.Aggregate(id, "", 1))
}
olpie101 commented 1 year ago

Thank you. This makes sense. Is there a way to test this? I noticed that if I attempt to use a WaitGroup, like in the example below, it becomes flaky.

const LookUpKey = "lookup"
type SomeProvideEvent struct {
    Key string
}

func (data SomeProvideEvent) ProvideLookup(p lookup.Provider) {
    p.Provide(LookUpKey, data.Key)
}

type SomeRemoveEvent struct {}

func (data SomeRemoveEvent) ProvideLookup(p lookup.Provider) {
    p.Remove(LookUpKey)
}

func example() {
    evts := []event.Event{
        event.New("foobarprovide", SomeProvideEvent{}, event.Aggregate("foo", id)),
        event.New("foobarremove", SomeRemoveEvent{}, event.Aggregate("foo", id)),
    }

    b := eventbus.New()
    s := eventstore.New()

    lk := lookup.New(s, b, []string{"foobarprovide", "foobarremove"})
    _, _ = lk.Run(context.Background())

    b.Publish(context.Background(), evts...)
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
    defer wg.Done()
    <-time.After(5 * time.Second)
    }()
    wg.Wait()

    _, ok := lk.Lookup(context.Background(), "someaggregate", LookUpKey, id)

   fmt.Println("found?", ok) // <- this is non-deterministic. Sometimes it's true. Other times its false
}
bounoable commented 1 year ago

This issue was actually caused by the event bus implementation. Your code should work now with v0.4.5.

olpie101 commented 9 months ago

Makes sense. Thank you for the clarification.