forked from mirrors/homebox
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:
parent
cceec06148
commit
2cbcc8bb1d
31 changed files with 458 additions and 208 deletions
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue