feat: WebSocket based implementation of server sent events for cache busting (#527)

* rough implementation of WS based event system for server side notifications of mutation

* fix test construction

* fix deadlock on event bus

* disable linter error

* add item mutation events

* remove old event bus code

* refactor event system to use composables

* refresh items table when new item is added

* fix create form errors

* cleanup unnecessary calls

* fix importer erorrs + limit fn calls on import
This commit is contained in:
Hayden 2023-08-02 13:00:57 -08:00 committed by GitHub
parent cceec06148
commit 2cbcc8bb1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 458 additions and 208 deletions

View file

@ -6,6 +6,7 @@ import (
"os"
"testing"
"github.com/hay-kot/homebox/backend/internal/core/services/reporting/eventbus"
"github.com/hay-kot/homebox/backend/internal/data/ent"
"github.com/hay-kot/homebox/backend/internal/data/repo"
"github.com/hay-kot/homebox/backend/pkgs/faker"
@ -13,7 +14,8 @@ import (
)
var (
fk = faker.NewFaker()
fk = faker.NewFaker()
tbus = eventbus.New()
tCtx = Context{}
tClient *ent.Client
@ -58,7 +60,7 @@ func TestMain(m *testing.M) {
}
tClient = client
tRepos = repo.New(tClient, os.TempDir()+"/homebox")
tRepos = repo.New(tClient, tbus, os.TempDir()+"/homebox")
tSvc = New(tRepos)
defer client.Close()

View file

@ -0,0 +1,85 @@
// / Package eventbus provides an interface for event bus.
package eventbus
import (
"sync"
"github.com/google/uuid"
)
type Event string
const (
EventLabelMutation Event = "label.mutation"
EventLocationMutation Event = "location.mutation"
EventItemMutation Event = "item.mutation"
)
type GroupMutationEvent struct {
GID uuid.UUID
}
type eventData struct {
event Event
data any
}
type EventBus struct {
started bool
ch chan eventData
mu sync.RWMutex
subscribers map[Event][]func(any)
}
func New() *EventBus {
return &EventBus{
ch: make(chan eventData, 10),
subscribers: map[Event][]func(any){
EventLabelMutation: {},
EventLocationMutation: {},
EventItemMutation: {},
},
}
}
func (e *EventBus) Run() {
if e.started {
panic("event bus already started")
}
e.started = true
for event := range e.ch {
e.mu.RLock()
arr, ok := e.subscribers[event.event]
e.mu.RUnlock()
if !ok {
continue
}
for _, fn := range arr {
fn(event.data)
}
}
}
func (e *EventBus) Publish(event Event, data any) {
e.ch <- eventData{
event: event,
data: data,
}
}
func (e *EventBus) Subscribe(event Event, fn func(any)) {
e.mu.Lock()
defer e.mu.Unlock()
arr, ok := e.subscribers[event]
if !ok {
panic("event not found")
}
e.subscribers[event] = append(arr, fn)
}