diff --git a/core/appmodule/event.go b/core/appmodule/event.go new file mode 100644 index 000000000000..0622d6b5a975 --- /dev/null +++ b/core/appmodule/event.go @@ -0,0 +1,32 @@ +package appmodule + +import ( + "context" + + "google.golang.org/protobuf/runtime/protoiface" +) + +// HasEventListeners is the extension interface that modules should implement to register +// event listeners. +type HasEventListeners interface { + AppModule + + // RegisterEventListeners registers the module's events listeners. + RegisterEventListeners(registrar *EventListenerRegistrar) +} + +// EventListenerRegistrar allows registering event listeners. +type EventListenerRegistrar struct { + listeners []any +} + +// GetListeners gets the event listeners that have been registered +func (e *EventListenerRegistrar) GetListeners() []any { + return e.listeners +} + +// RegisterEventListener registers an event listener for event type E. If a non-nil error is returned by the listener, +// it will cause the process which emitted the event to fail. +func RegisterEventListener[E protoiface.MessageV1](registrar *EventListenerRegistrar, listener func(context.Context, E) error) { + registrar.listeners = append(registrar.listeners, listener) +} diff --git a/core/appmodule/event_test.go b/core/appmodule/event_test.go new file mode 100644 index 000000000000..739bfa6fb3c9 --- /dev/null +++ b/core/appmodule/event_test.go @@ -0,0 +1,17 @@ +package appmodule + +import ( + "context" + "reflect" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestEventListenerRegistrar(t *testing.T) { + registrar := &EventListenerRegistrar{} + RegisterEventListener(registrar, func(ctx context.Context, dummy *timestamppb.Timestamp) error { return nil }) + require.Len(t, registrar.listeners, 1) + require.Equal(t, reflect.Func, reflect.TypeOf(registrar.listeners[0]).Kind()) +}