From be3dd42eaccaba73060a60cf1d32c982da8c78ad Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Mon, 12 Dec 2022 19:21:41 +0200 Subject: [PATCH] batched rel references and added test for the batch delete processing --- apis/record_crud_test.go | 6 +- daos/base.go | 12 +- daos/record.go | 16 +-- go.mod | 2 +- go.sum | 4 +- tests/app.go | 230 ++++++++++++++++----------------------- 6 files changed, 111 insertions(+), 159 deletions(-) diff --git a/apis/record_crud_test.go b/apis/record_crud_test.go index 5965a32d..b6ada59a 100644 --- a/apis/record_crud_test.go +++ b/apis/record_crud_test.go @@ -684,7 +684,7 @@ func TestRecordCrudDelete(t *testing.T) { }, }, { - Name: "authenticated record that does match the collection delete rule", + Name: "authenticated record that match the collection delete rule", Method: http.MethodDelete, Url: "/api/collections/users/records/4q1xlclmfloku33", RequestHeaders: map[string]string{ @@ -693,9 +693,9 @@ func TestRecordCrudDelete(t *testing.T) { }, ExpectedStatus: 204, ExpectedEvents: map[string]int{ - "OnModelAfterDelete": 1, + "OnModelAfterDelete": 3, // +2 because of the external auths + "OnModelBeforeDelete": 3, // +2 because of the external auths "OnModelAfterUpdate": 1, - "OnModelBeforeDelete": 1, "OnModelBeforeUpdate": 1, "OnRecordAfterDeleteRequest": 1, "OnRecordBeforeDeleteRequest": 1, diff --git a/daos/base.go b/daos/base.go index 7a1c2cee..46cc0f18 100644 --- a/daos/base.go +++ b/daos/base.go @@ -111,7 +111,7 @@ func (dao *Dao) RunInTransaction(fn func(txDao *Dao) error) error { case *dbx.Tx: // nested transactions are not supported by default // so execute the function within the current transaction - + // --- // create a new dao with the same hooks to avoid semaphore deadlock when nesting txDao := New(txOrDB) txDao.BeforeCreateFunc = dao.BeforeCreateFunc @@ -320,12 +320,10 @@ Retry: if attempts == 2 { // assign new Dao without the before hooks to avoid triggering // the already fired before callbacks multiple times - retryDao = &Dao{ - db: dao.db, - AfterCreateFunc: dao.AfterCreateFunc, - AfterUpdateFunc: dao.AfterUpdateFunc, - AfterDeleteFunc: dao.AfterDeleteFunc, - } + retryDao = New(dao.db) + retryDao.AfterCreateFunc = dao.AfterCreateFunc + retryDao.AfterUpdateFunc = dao.AfterUpdateFunc + retryDao.AfterDeleteFunc = dao.AfterDeleteFunc } // execute diff --git a/daos/record.go b/daos/record.go index 91104d6b..445cbf1e 100644 --- a/daos/record.go +++ b/daos/record.go @@ -433,21 +433,21 @@ func (dao *Dao) cascadeRecordDelete(mainRecord *models.Record, refs map[*models. break } - perPage := 200 - pages := int(math.Ceil(float64(total) / float64(perPage))) + perWorkers := 50 + workers := int(math.Ceil(float64(total) / float64(perWorkers))) batchErr := func() error { ch := make(chan error) defer close(ch) - for i := 0; i < pages; i++ { + for i := 0; i < workers; i++ { var chunks []dbx.NullStringMap - if len(rows) <= perPage { - chunks = rows[0:] + if len(rows) <= perWorkers { + chunks = rows rows = nil } else { - chunks = rows[0:perPage] - rows = rows[perPage:] + chunks = rows[:perWorkers] + rows = rows[perWorkers:] } go func() { @@ -456,7 +456,7 @@ func (dao *Dao) cascadeRecordDelete(mainRecord *models.Record, refs map[*models. }() } - for i := 0; i < pages; i++ { + for i := 0; i < workers; i++ { if err := <-ch; err != nil { return err } diff --git a/go.mod b/go.mod index 7a813311..30772286 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/AlecAivazis/survey/v2 v2.3.6 - github.com/aws/aws-sdk-go v1.44.156 + github.com/aws/aws-sdk-go v1.44.157 github.com/disintegration/imaging v1.6.2 github.com/domodwyer/mailyak/v3 v3.3.4 github.com/dop251/goja v0.0.0-20221118162653-d4bf6fde1b86 diff --git a/go.sum b/go.sum index 868f2d5e..f5e2b614 100644 --- a/go.sum +++ b/go.sum @@ -206,8 +206,8 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4 github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.156 h1:3RhbBTZ87HoI5OP2JjcKdd5qOnyo9YOAW8+Bb/h0vSE= -github.com/aws/aws-sdk-go v1.44.156/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.157 h1:JVBPpEWC8+yA7CbfAuTl/ZFFlHS3yoqWFqxFyTCISwg= +github.com/aws/aws-sdk-go v1.44.157/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= github.com/aws/aws-sdk-go-v2 v1.17.2 h1:r0yRZInwiPBNpQ4aDy/Ssh3ROWsGtKDwar2JS8Lm+N8= diff --git a/tests/app.go b/tests/app.go index 71744301..6068a2ae 100644 --- a/tests/app.go +++ b/tests/app.go @@ -7,6 +7,7 @@ import ( "path" "path/filepath" "runtime" + "sync" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/mailer" @@ -16,6 +17,8 @@ import ( type TestApp struct { *core.BaseApp + mux sync.Mutex + // EventCalls defines a map to inspect which app events // (and how many times) were triggered. // @@ -42,15 +45,35 @@ func (t *TestApp) Cleanup() { } func (t *TestApp) NewMailClient() mailer.Mailer { + t.mux.Lock() + defer t.mux.Unlock() + t.TestMailer.Reset() + return t.TestMailer } // ResetEventCalls resets the EventCalls counter. func (t *TestApp) ResetEventCalls() { + t.mux.Lock() + defer t.mux.Unlock() + t.EventCalls = make(map[string]int) } +func (t *TestApp) registerEventCall(name string) error { + t.mux.Lock() + defer t.mux.Unlock() + + if t.EventCalls == nil { + t.EventCalls = make(map[string]int) + } + + t.EventCalls[name]++ + + return nil +} + // NewTestApp creates and initializes a test application instance. // // It is the caller's responsibility to call `app.Cleanup()` @@ -88,348 +111,279 @@ func NewTestApp(optTestDataDir ...string) (*TestApp, error) { } t.OnBeforeApiError().Add(func(e *core.ApiErrorEvent) error { - t.EventCalls["OnBeforeApiError"]++ - return nil + return t.registerEventCall("OnBeforeApiError") }) t.OnAfterApiError().Add(func(e *core.ApiErrorEvent) error { - t.EventCalls["OnAfterApiError"]++ - return nil + return t.registerEventCall("OnAfterApiError") }) t.OnModelBeforeCreate().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelBeforeCreate"]++ - return nil + return t.registerEventCall("OnModelBeforeCreate") }) t.OnModelAfterCreate().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelAfterCreate"]++ - return nil + return t.registerEventCall("OnModelAfterCreate") }) t.OnModelBeforeUpdate().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelBeforeUpdate"]++ - return nil + return t.registerEventCall("OnModelBeforeUpdate") }) t.OnModelAfterUpdate().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelAfterUpdate"]++ - return nil + return t.registerEventCall("OnModelAfterUpdate") }) t.OnModelBeforeDelete().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelBeforeDelete"]++ - return nil + return t.registerEventCall("OnModelBeforeDelete") }) t.OnModelAfterDelete().Add(func(e *core.ModelEvent) error { - t.EventCalls["OnModelAfterDelete"]++ - return nil + return t.registerEventCall("OnModelAfterDelete") }) t.OnRecordsListRequest().Add(func(e *core.RecordsListEvent) error { - t.EventCalls["OnRecordsListRequest"]++ - return nil + return t.registerEventCall("OnRecordsListRequest") }) t.OnRecordViewRequest().Add(func(e *core.RecordViewEvent) error { - t.EventCalls["OnRecordViewRequest"]++ - return nil + return t.registerEventCall("OnRecordViewRequest") }) t.OnRecordBeforeCreateRequest().Add(func(e *core.RecordCreateEvent) error { - t.EventCalls["OnRecordBeforeCreateRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeCreateRequest") }) t.OnRecordAfterCreateRequest().Add(func(e *core.RecordCreateEvent) error { - t.EventCalls["OnRecordAfterCreateRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterCreateRequest") }) t.OnRecordBeforeUpdateRequest().Add(func(e *core.RecordUpdateEvent) error { - t.EventCalls["OnRecordBeforeUpdateRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeUpdateRequest") }) t.OnRecordAfterUpdateRequest().Add(func(e *core.RecordUpdateEvent) error { - t.EventCalls["OnRecordAfterUpdateRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterUpdateRequest") }) t.OnRecordBeforeDeleteRequest().Add(func(e *core.RecordDeleteEvent) error { - t.EventCalls["OnRecordBeforeDeleteRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeDeleteRequest") }) t.OnRecordAfterDeleteRequest().Add(func(e *core.RecordDeleteEvent) error { - t.EventCalls["OnRecordAfterDeleteRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterDeleteRequest") }) t.OnRecordAuthRequest().Add(func(e *core.RecordAuthEvent) error { - t.EventCalls["OnRecordAuthRequest"]++ - return nil + return t.registerEventCall("OnRecordAuthRequest") }) t.OnRecordBeforeRequestPasswordResetRequest().Add(func(e *core.RecordRequestPasswordResetEvent) error { - t.EventCalls["OnRecordBeforeRequestPasswordResetRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeRequestPasswordResetRequest") }) t.OnRecordAfterRequestPasswordResetRequest().Add(func(e *core.RecordRequestPasswordResetEvent) error { - t.EventCalls["OnRecordAfterRequestPasswordResetRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterRequestPasswordResetRequest") }) t.OnRecordBeforeConfirmPasswordResetRequest().Add(func(e *core.RecordConfirmPasswordResetEvent) error { - t.EventCalls["OnRecordBeforeConfirmPasswordResetRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeConfirmPasswordResetRequest") }) t.OnRecordAfterConfirmPasswordResetRequest().Add(func(e *core.RecordConfirmPasswordResetEvent) error { - t.EventCalls["OnRecordAfterConfirmPasswordResetRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterConfirmPasswordResetRequest") }) t.OnRecordBeforeRequestVerificationRequest().Add(func(e *core.RecordRequestVerificationEvent) error { - t.EventCalls["OnRecordBeforeRequestVerificationRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeRequestVerificationRequest") }) t.OnRecordAfterRequestVerificationRequest().Add(func(e *core.RecordRequestVerificationEvent) error { - t.EventCalls["OnRecordAfterRequestVerificationRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterRequestVerificationRequest") }) t.OnRecordBeforeConfirmVerificationRequest().Add(func(e *core.RecordConfirmVerificationEvent) error { - t.EventCalls["OnRecordBeforeConfirmVerificationRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeConfirmVerificationRequest") }) t.OnRecordAfterConfirmVerificationRequest().Add(func(e *core.RecordConfirmVerificationEvent) error { - t.EventCalls["OnRecordAfterConfirmVerificationRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterConfirmVerificationRequest") }) t.OnRecordBeforeRequestEmailChangeRequest().Add(func(e *core.RecordRequestEmailChangeEvent) error { - t.EventCalls["OnRecordBeforeRequestEmailChangeRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeRequestEmailChangeRequest") }) t.OnRecordAfterRequestEmailChangeRequest().Add(func(e *core.RecordRequestEmailChangeEvent) error { - t.EventCalls["OnRecordAfterRequestEmailChangeRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterRequestEmailChangeRequest") }) t.OnRecordBeforeConfirmEmailChangeRequest().Add(func(e *core.RecordConfirmEmailChangeEvent) error { - t.EventCalls["OnRecordBeforeConfirmEmailChangeRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeConfirmEmailChangeRequest") }) t.OnRecordAfterConfirmEmailChangeRequest().Add(func(e *core.RecordConfirmEmailChangeEvent) error { - t.EventCalls["OnRecordAfterConfirmEmailChangeRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterConfirmEmailChangeRequest") }) t.OnRecordListExternalAuthsRequest().Add(func(e *core.RecordListExternalAuthsEvent) error { - t.EventCalls["OnRecordListExternalAuthsRequest"]++ - return nil + return t.registerEventCall("OnRecordListExternalAuthsRequest") }) t.OnRecordBeforeUnlinkExternalAuthRequest().Add(func(e *core.RecordUnlinkExternalAuthEvent) error { - t.EventCalls["OnRecordBeforeUnlinkExternalAuthRequest"]++ - return nil + return t.registerEventCall("OnRecordBeforeUnlinkExternalAuthRequest") }) t.OnRecordAfterUnlinkExternalAuthRequest().Add(func(e *core.RecordUnlinkExternalAuthEvent) error { - t.EventCalls["OnRecordAfterUnlinkExternalAuthRequest"]++ - return nil + return t.registerEventCall("OnRecordAfterUnlinkExternalAuthRequest") }) t.OnMailerBeforeAdminResetPasswordSend().Add(func(e *core.MailerAdminEvent) error { - t.EventCalls["OnMailerBeforeAdminResetPasswordSend"]++ - return nil + return t.registerEventCall("OnMailerBeforeAdminResetPasswordSend") }) t.OnMailerAfterAdminResetPasswordSend().Add(func(e *core.MailerAdminEvent) error { - t.EventCalls["OnMailerAfterAdminResetPasswordSend"]++ - return nil + return t.registerEventCall("OnMailerAfterAdminResetPasswordSend") }) t.OnMailerBeforeRecordResetPasswordSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerBeforeRecordResetPasswordSend"]++ - return nil + return t.registerEventCall("OnMailerBeforeRecordResetPasswordSend") }) t.OnMailerAfterRecordResetPasswordSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerAfterRecordResetPasswordSend"]++ - return nil + return t.registerEventCall("OnMailerAfterRecordResetPasswordSend") }) t.OnMailerBeforeRecordVerificationSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerBeforeRecordVerificationSend"]++ - return nil + return t.registerEventCall("OnMailerBeforeRecordVerificationSend") }) t.OnMailerAfterRecordVerificationSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerAfterRecordVerificationSend"]++ - return nil + return t.registerEventCall("OnMailerAfterRecordVerificationSend") }) t.OnMailerBeforeRecordChangeEmailSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerBeforeRecordChangeEmailSend"]++ - return nil + return t.registerEventCall("OnMailerBeforeRecordChangeEmailSend") }) t.OnMailerAfterRecordChangeEmailSend().Add(func(e *core.MailerRecordEvent) error { - t.EventCalls["OnMailerAfterRecordChangeEmailSend"]++ - return nil + return t.registerEventCall("OnMailerAfterRecordChangeEmailSend") }) t.OnRealtimeConnectRequest().Add(func(e *core.RealtimeConnectEvent) error { - t.EventCalls["OnRealtimeConnectRequest"]++ - return nil + return t.registerEventCall("OnRealtimeConnectRequest") }) t.OnRealtimeDisconnectRequest().Add(func(e *core.RealtimeDisconnectEvent) error { - t.EventCalls["OnRealtimeDisconnectRequest"]++ - return nil + return t.registerEventCall("OnRealtimeDisconnectRequest") }) t.OnRealtimeBeforeMessageSend().Add(func(e *core.RealtimeMessageEvent) error { - t.EventCalls["OnRealtimeBeforeMessageSend"]++ - return nil + return t.registerEventCall("OnRealtimeBeforeMessageSend") }) t.OnRealtimeAfterMessageSend().Add(func(e *core.RealtimeMessageEvent) error { - t.EventCalls["OnRealtimeAfterMessageSend"]++ - return nil + return t.registerEventCall("OnRealtimeAfterMessageSend") }) t.OnRealtimeBeforeSubscribeRequest().Add(func(e *core.RealtimeSubscribeEvent) error { - t.EventCalls["OnRealtimeBeforeSubscribeRequest"]++ - return nil + return t.registerEventCall("OnRealtimeBeforeSubscribeRequest") }) t.OnRealtimeAfterSubscribeRequest().Add(func(e *core.RealtimeSubscribeEvent) error { - t.EventCalls["OnRealtimeAfterSubscribeRequest"]++ - return nil + return t.registerEventCall("OnRealtimeAfterSubscribeRequest") }) t.OnSettingsListRequest().Add(func(e *core.SettingsListEvent) error { - t.EventCalls["OnSettingsListRequest"]++ - return nil + return t.registerEventCall("OnSettingsListRequest") }) t.OnSettingsBeforeUpdateRequest().Add(func(e *core.SettingsUpdateEvent) error { - t.EventCalls["OnSettingsBeforeUpdateRequest"]++ - return nil + return t.registerEventCall("OnSettingsBeforeUpdateRequest") }) t.OnSettingsAfterUpdateRequest().Add(func(e *core.SettingsUpdateEvent) error { - t.EventCalls["OnSettingsAfterUpdateRequest"]++ - return nil + return t.registerEventCall("OnSettingsAfterUpdateRequest") }) t.OnCollectionsListRequest().Add(func(e *core.CollectionsListEvent) error { - t.EventCalls["OnCollectionsListRequest"]++ - return nil + return t.registerEventCall("OnCollectionsListRequest") }) t.OnCollectionViewRequest().Add(func(e *core.CollectionViewEvent) error { - t.EventCalls["OnCollectionViewRequest"]++ - return nil + return t.registerEventCall("OnCollectionViewRequest") }) t.OnCollectionBeforeCreateRequest().Add(func(e *core.CollectionCreateEvent) error { - t.EventCalls["OnCollectionBeforeCreateRequest"]++ - return nil + return t.registerEventCall("OnCollectionBeforeCreateRequest") }) t.OnCollectionAfterCreateRequest().Add(func(e *core.CollectionCreateEvent) error { - t.EventCalls["OnCollectionAfterCreateRequest"]++ - return nil + return t.registerEventCall("OnCollectionAfterCreateRequest") }) t.OnCollectionBeforeUpdateRequest().Add(func(e *core.CollectionUpdateEvent) error { - t.EventCalls["OnCollectionBeforeUpdateRequest"]++ - return nil + return t.registerEventCall("OnCollectionBeforeUpdateRequest") }) t.OnCollectionAfterUpdateRequest().Add(func(e *core.CollectionUpdateEvent) error { - t.EventCalls["OnCollectionAfterUpdateRequest"]++ - return nil + return t.registerEventCall("OnCollectionAfterUpdateRequest") }) t.OnCollectionBeforeDeleteRequest().Add(func(e *core.CollectionDeleteEvent) error { - t.EventCalls["OnCollectionBeforeDeleteRequest"]++ - return nil + return t.registerEventCall("OnCollectionBeforeDeleteRequest") }) t.OnCollectionAfterDeleteRequest().Add(func(e *core.CollectionDeleteEvent) error { - t.EventCalls["OnCollectionAfterDeleteRequest"]++ - return nil + return t.registerEventCall("OnCollectionAfterDeleteRequest") }) t.OnCollectionsBeforeImportRequest().Add(func(e *core.CollectionsImportEvent) error { - t.EventCalls["OnCollectionsBeforeImportRequest"]++ - return nil + return t.registerEventCall("OnCollectionsBeforeImportRequest") }) t.OnCollectionsAfterImportRequest().Add(func(e *core.CollectionsImportEvent) error { - t.EventCalls["OnCollectionsAfterImportRequest"]++ - return nil + return t.registerEventCall("OnCollectionsAfterImportRequest") }) t.OnAdminsListRequest().Add(func(e *core.AdminsListEvent) error { - t.EventCalls["OnAdminsListRequest"]++ - return nil + return t.registerEventCall("OnAdminsListRequest") }) t.OnAdminViewRequest().Add(func(e *core.AdminViewEvent) error { - t.EventCalls["OnAdminViewRequest"]++ - return nil + return t.registerEventCall("OnAdminViewRequest") }) t.OnAdminBeforeCreateRequest().Add(func(e *core.AdminCreateEvent) error { - t.EventCalls["OnAdminBeforeCreateRequest"]++ - return nil + return t.registerEventCall("OnAdminBeforeCreateRequest") }) t.OnAdminAfterCreateRequest().Add(func(e *core.AdminCreateEvent) error { - t.EventCalls["OnAdminAfterCreateRequest"]++ - return nil + return t.registerEventCall("OnAdminAfterCreateRequest") }) t.OnAdminBeforeUpdateRequest().Add(func(e *core.AdminUpdateEvent) error { - t.EventCalls["OnAdminBeforeUpdateRequest"]++ - return nil + return t.registerEventCall("OnAdminBeforeUpdateRequest") }) t.OnAdminAfterUpdateRequest().Add(func(e *core.AdminUpdateEvent) error { - t.EventCalls["OnAdminAfterUpdateRequest"]++ - return nil + return t.registerEventCall("OnAdminAfterUpdateRequest") }) t.OnAdminBeforeDeleteRequest().Add(func(e *core.AdminDeleteEvent) error { - t.EventCalls["OnAdminBeforeDeleteRequest"]++ - return nil + return t.registerEventCall("OnAdminBeforeDeleteRequest") }) t.OnAdminAfterDeleteRequest().Add(func(e *core.AdminDeleteEvent) error { - t.EventCalls["OnAdminAfterDeleteRequest"]++ - return nil + return t.registerEventCall("OnAdminAfterDeleteRequest") }) t.OnAdminAuthRequest().Add(func(e *core.AdminAuthEvent) error { - t.EventCalls["OnAdminAuthRequest"]++ - return nil + return t.registerEventCall("OnAdminAuthRequest") }) t.OnFileDownloadRequest().Add(func(e *core.FileDownloadEvent) error { - t.EventCalls["OnFileDownloadRequest"]++ - return nil + return t.registerEventCall("OnFileDownloadRequest") }) return t, nil