SearchV2: instant local updates, folder events (#50001) (#50194)

(cherry picked from commit d2868a1ce7)

Co-authored-by: Alexander Emelin <frvzmb@gmail.com>
This commit is contained in:
Grot (@grafanabot)
2022-06-03 22:29:48 +02:00
committed by GitHub
co-authored by Alexander Emelin
parent b9621d08a5
commit ed169da58c
9 changed files with 728 additions and 35 deletions
+40 -12
View File
@@ -24,6 +24,7 @@ type EntityType string
const (
EntityTypeDashboard EntityType = "dashboard"
EntityTypeFolder EntityType = "folder"
)
// CreateDatabaseEntityId creates entityId for entities stored in the existing SQL tables
@@ -51,6 +52,8 @@ type SaveEventCmd struct {
EventType EntityEventType
}
type EventHandler func(ctx context.Context, e *EntityEvent) error
// EntityEventsService is a temporary solution to support change notifications in an HA setup
// With this service each system can query for any events that have happened since a fixed time
//go:generate mockery --name EntityEventsService --structname MockEntityEventsService --inpackage --filename entity_events_mock.go
@@ -60,6 +63,7 @@ type EntityEventsService interface {
SaveEvent(ctx context.Context, cmd SaveEventCmd) error
GetLastEvent(ctx context.Context) (*EntityEvent, error)
GetAllEventsAfter(ctx context.Context, id int64) ([]*EntityEvent, error)
OnEvent(handler EventHandler)
deleteEventsOlderThan(ctx context.Context, duration time.Duration) error
}
@@ -70,27 +74,48 @@ func ProvideEntityEventsService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore, f
}
return &entityEventService{
sql: sqlStore,
features: features,
log: log.New("entity-events"),
sql: sqlStore,
features: features,
log: log.New("entity-events"),
eventHandlers: make([]EventHandler, 0),
}
}
type entityEventService struct {
sql *sqlstore.SQLStore
log log.Logger
features featuremgmt.FeatureToggles
sql *sqlstore.SQLStore
log log.Logger
features featuremgmt.FeatureToggles
eventHandlers []EventHandler
}
func (e *entityEventService) SaveEvent(ctx context.Context, cmd SaveEventCmd) error {
return e.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Insert(&EntityEvent{
EventType: cmd.EventType,
EntityId: cmd.EntityId,
Created: time.Now().Unix(),
})
entityEvent := &EntityEvent{
EventType: cmd.EventType,
EntityId: cmd.EntityId,
Created: time.Now().Unix(),
}
err := e.sql.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Insert(entityEvent)
return err
})
if err != nil {
return err
}
return e.broadcastEvent(ctx, entityEvent)
}
func (e *entityEventService) broadcastEvent(ctx context.Context, event *EntityEvent) error {
for _, h := range e.eventHandlers {
err := h(ctx, event)
if err != nil {
return err
}
}
return nil
}
func (e *entityEventService) OnEvent(handler EventHandler) {
e.eventHandlers = append(e.eventHandlers, handler)
}
func (e *entityEventService) GetLastEvent(ctx context.Context) (*EntityEvent, error) {
@@ -164,6 +189,9 @@ func (d dummyEntityEventsService) SaveEvent(ctx context.Context, cmd SaveEventCm
return nil
}
func (d dummyEntityEventsService) OnEvent(handler EventHandler) {
}
func (d dummyEntityEventsService) GetLastEvent(ctx context.Context) (*EntityEvent, error) {
return nil, nil
}
+21 -1
View File
@@ -1,4 +1,4 @@
// Code generated by mockery v2.10.6. DO NOT EDIT.
// Code generated by mockery v2.12.3. DO NOT EDIT.
package store
@@ -74,6 +74,11 @@ func (_m *MockEntityEventsService) IsDisabled() bool {
return r0
}
// OnEvent provides a mock function with given fields: handler
func (_m *MockEntityEventsService) OnEvent(handler EventHandler) {
_m.Called(handler)
}
// Run provides a mock function with given fields: ctx
func (_m *MockEntityEventsService) Run(ctx context.Context) error {
ret := _m.Called(ctx)
@@ -115,3 +120,18 @@ func (_m *MockEntityEventsService) deleteEventsOlderThan(ctx context.Context, du
return r0
}
type NewMockEntityEventsServiceT interface {
mock.TestingT
Cleanup(func())
}
// NewMockEntityEventsService creates a new instance of MockEntityEventsService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewMockEntityEventsService(t NewMockEntityEventsServiceT) *MockEntityEventsService {
mock := &MockEntityEventsService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}