Skip to content

Commit

Permalink
[pocketbase#590] fixed realtime events bind order by adding hooks.PreAdd
Browse files Browse the repository at this point in the history
  • Loading branch information
ganigeorgiev committed Sep 21, 2022
1 parent 9a8c9dd commit 9540678
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 13 deletions.
8 changes: 4 additions & 4 deletions apis/realtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (api *realtimeApi) bindEvents() {
adminTable := (&models.Admin{}).TableName()

// update user/admin auth state
api.app.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error {
api.app.OnModelAfterUpdate().PreAdd(func(e *core.ModelEvent) error {
modelTable := e.Model.TableName()

var contextKey string
Expand All @@ -190,7 +190,7 @@ func (api *realtimeApi) bindEvents() {
})

// remove user/admin client(s)
api.app.OnModelAfterDelete().Add(func(e *core.ModelEvent) error {
api.app.OnModelAfterDelete().PreAdd(func(e *core.ModelEvent) error {
modelTable := e.Model.TableName()

var contextKey string
Expand All @@ -213,14 +213,14 @@ func (api *realtimeApi) bindEvents() {
return nil
})

api.app.OnModelAfterCreate().Add(func(e *core.ModelEvent) error {
api.app.OnModelAfterCreate().PreAdd(func(e *core.ModelEvent) error {
if record, ok := e.Model.(*models.Record); ok {
api.broadcastRecord("create", record)
}
return nil
})

api.app.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error {
api.app.OnModelAfterUpdate().PreAdd(func(e *core.ModelEvent) error {
if record, ok := e.Model.(*models.Record); ok {
api.broadcastRecord("update", record)
}
Expand Down
6 changes: 3 additions & 3 deletions core/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ func (app *BaseApp) initLogsDB() error {
return connectErr
}

app.logsDao = app.createDao(app.logsDB)
app.logsDao = daos.New(app.logsDB)

return nil
}
Expand All @@ -740,12 +740,12 @@ func (app *BaseApp) initDataDB() error {
}
}

app.dao = app.createDao(app.db)
app.dao = app.createDaoWithHooks(app.db)

return nil
}

func (app *BaseApp) createDao(db dbx.Builder) *daos.Dao {
func (app *BaseApp) createDaoWithHooks(db dbx.Builder) *daos.Dao {
dao := daos.New(db)

dao.BeforeCreateFunc = func(eventDao *daos.Dao, m models.Model) error {
Expand Down
13 changes: 12 additions & 1 deletion tools/hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,18 @@ type Hook[T any] struct {
handlers []Handler[T]
}

// Add registers a new handler to the hook.
// PreAdd registers a new handler to the hook by prepending it to the existing queue.
func (h *Hook[T]) PreAdd(fn Handler[T]) {
h.mux.Lock()
defer h.mux.Unlock()

// minimize allocations by shifting the slice
h.handlers = append(h.handlers, nil)
copy(h.handlers[1:], h.handlers)
h.handlers[0] = fn
}

// Add registers a new handler to the hook by appending it to the existing queue.
func (h *Hook[T]) Add(fn Handler[T]) {
h.mux.Lock()
defer h.mux.Unlock()
Expand Down
26 changes: 21 additions & 5 deletions tools/hook/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,34 @@ import (
"testing"
)

func TestAdd(t *testing.T) {
func TestAddAndPreAdd(t *testing.T) {
h := Hook[int]{}

if total := len(h.handlers); total != 0 {
t.Fatalf("Expected no handlers, found %d", total)
}

h.Add(func(data int) error { return nil })
h.Add(func(data int) error { return nil })
triggerSequence := ""

if total := len(h.handlers); total != 2 {
t.Fatalf("Expected 2 handlers, found %d", total)
f1 := func(data int) error { triggerSequence += "f1"; return nil }
f2 := func(data int) error { triggerSequence += "f2"; return nil }
f3 := func(data int) error { triggerSequence += "f3"; return nil }
f4 := func(data int) error { triggerSequence += "f4"; return nil }

h.Add(f1)
h.Add(f2)
h.PreAdd(f3)
h.PreAdd(f4)
h.Trigger(1)

if total := len(h.handlers); total != 4 {
t.Fatalf("Expected %d handlers, found %d", 4, total)
}

expectedTriggerSequence := "f4f3f1f2"

if triggerSequence != expectedTriggerSequence {
t.Fatalf("Expected trigger sequence %s, got %s", expectedTriggerSequence, triggerSequence)
}
}

Expand Down

0 comments on commit 9540678

Please sign in to comment.