feat(search): remove userid from indexspace methods

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg
2024-06-25 10:01:37 +02:00
parent 9d7ea44b2e
commit 63686d6cd7
8 changed files with 113 additions and 130 deletions
+4 -5
View File
@@ -4,14 +4,13 @@ import (
"sync"
"time"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
)
// SpaceDebouncer debounces operations on spaces for a configurable amount of time
type SpaceDebouncer struct {
after time.Duration
f func(id *provider.StorageSpaceId, userID *user.UserId)
f func(id *provider.StorageSpaceId)
pending map[string]*time.Timer
inProgress sync.Map
@@ -19,7 +18,7 @@ type SpaceDebouncer struct {
}
// NewSpaceDebouncer returns a new SpaceDebouncer instance
func NewSpaceDebouncer(d time.Duration, f func(id *provider.StorageSpaceId, userID *user.UserId)) *SpaceDebouncer {
func NewSpaceDebouncer(d time.Duration, f func(id *provider.StorageSpaceId)) *SpaceDebouncer {
return &SpaceDebouncer{
after: d,
f: f,
@@ -29,7 +28,7 @@ func NewSpaceDebouncer(d time.Duration, f func(id *provider.StorageSpaceId, user
}
// Debounce restars the debounce timer for the given space
func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, userID *user.UserId) {
func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId) {
d.mutex.Lock()
defer d.mutex.Unlock()
@@ -48,6 +47,6 @@ func (d *SpaceDebouncer) Debounce(id *provider.StorageSpaceId, userID *user.User
d.inProgress.Store(id.OpaqueId, true)
defer d.inProgress.Delete(id.OpaqueId)
d.f(id, userID)
d.f(id)
})
}
+12 -16
View File
@@ -4,7 +4,6 @@ import (
"sync/atomic"
"time"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@@ -17,9 +16,6 @@ var _ = Describe("SpaceDebouncer", func() {
callCount atomic.Int32
userId = &user.UserId{
OpaqueId: "user",
}
spaceid = &sprovider.StorageSpaceId{
OpaqueId: "spaceid",
}
@@ -27,7 +23,7 @@ var _ = Describe("SpaceDebouncer", func() {
BeforeEach(func() {
callCount = atomic.Int32{}
debouncer = search.NewSpaceDebouncer(50*time.Millisecond, func(id *sprovider.StorageSpaceId, _ *user.UserId) {
debouncer = search.NewSpaceDebouncer(50*time.Millisecond, func(id *sprovider.StorageSpaceId) {
if id.OpaqueId == "spaceid" {
callCount.Add(1)
}
@@ -35,22 +31,22 @@ var _ = Describe("SpaceDebouncer", func() {
})
It("debounces", func() {
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid)
debouncer.Debounce(spaceid)
debouncer.Debounce(spaceid)
Eventually(func() int {
return int(callCount.Load())
}, "200ms").Should(Equal(1))
})
It("works multiple times", func() {
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid)
debouncer.Debounce(spaceid)
debouncer.Debounce(spaceid)
time.Sleep(100 * time.Millisecond)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid)
debouncer.Debounce(spaceid)
Eventually(func() int {
return int(callCount.Load())
@@ -58,16 +54,16 @@ var _ = Describe("SpaceDebouncer", func() {
})
It("doesn't trigger twice simultaneously", func() {
debouncer = search.NewSpaceDebouncer(50*time.Millisecond, func(id *sprovider.StorageSpaceId, _ *user.UserId) {
debouncer = search.NewSpaceDebouncer(50*time.Millisecond, func(id *sprovider.StorageSpaceId) {
if id.OpaqueId == "spaceid" {
callCount.Add(1)
}
time.Sleep(300 * time.Millisecond)
})
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid)
time.Sleep(100 * time.Millisecond) // Let it trigger once
debouncer.Debounce(spaceid, userId)
debouncer.Debounce(spaceid)
time.Sleep(100 * time.Millisecond) // shouldn't trigger as the other run is still in progress
Expect(int(callCount.Load())).To(Equal(1))
+16 -38
View File
@@ -3,7 +3,6 @@ package search
import (
"time"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/storagespace"
@@ -52,21 +51,9 @@ func HandleEvents(s Searcher, bus events.Consumer, logger log.Logger, cfg *confi
}
}
getUser := func(users ...*user.UserId) *user.UserId {
for _, u := range users {
if u == nil {
continue
}
return u
}
return nil
}
indexSpaceDebouncer := NewSpaceDebouncer(time.Duration(cfg.Events.DebounceDuration)*time.Millisecond, func(id *provider.StorageSpaceId, userID *user.UserId) {
if err := s.IndexSpace(id, userID); err != nil {
logger.Error().Err(err).Interface("spaceID", id).Interface("userID", userID).Msg("error while indexing a space")
indexSpaceDebouncer := NewSpaceDebouncer(time.Duration(cfg.Events.DebounceDuration)*time.Millisecond, func(id *provider.StorageSpaceId) {
if err := s.IndexSpace(id); err != nil {
logger.Error().Err(err).Interface("spaceID", id).Msg("error while indexing a space")
}
})
@@ -77,41 +64,32 @@ func HandleEvents(s Searcher, bus events.Consumer, logger log.Logger, cfg *confi
go func() {
logger.Debug().Interface("event", e).Msg("updating index")
var err error
switch ev := e.Event.(type) {
case events.ItemTrashed:
u := getUser(ev.SpaceOwner, ev.Executant)
s.TrashItem(ev.ID)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), u)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.ItemMoved:
u := getUser(ev.SpaceOwner, ev.Executant)
s.MoveItem(ev.Ref, u)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), getUser(ev.SpaceOwner, ev.Executant))
s.MoveItem(ev.Ref)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.ItemRestored:
u := getUser(ev.SpaceOwner, ev.Executant)
s.RestoreItem(ev.Ref, u)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), u)
s.RestoreItem(ev.Ref)
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.ContainerCreated:
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), getUser(ev.SpaceOwner, ev.Executant))
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.FileTouched:
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), getUser(ev.SpaceOwner, ev.Executant))
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.FileVersionRestored:
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), getUser(ev.SpaceOwner, ev.Executant))
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.TagsAdded:
s.UpsertItem(ev.Ref, ev.Executant)
s.UpsertItem(ev.Ref)
case events.TagsRemoved:
s.UpsertItem(ev.Ref, ev.Executant)
s.UpsertItem(ev.Ref)
case events.FileUploaded:
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref), getUser(ev.SpaceOwner, ev.Executant))
indexSpaceDebouncer.Debounce(getSpaceID(ev.Ref))
case events.UploadReady:
indexSpaceDebouncer.Debounce(getSpaceID(ev.FileRef), getUser(ev.SpaceOwner, ev.ExecutingUser.GetId()))
indexSpaceDebouncer.Debounce(getSpaceID(ev.FileRef))
case events.SpaceRenamed:
indexSpaceDebouncer.Debounce(ev.ID, getUser(ev.Executant))
}
if err != nil {
logger.Error().Err(err).Interface("event", e)
indexSpaceDebouncer.Debounce(ev.ID)
}
}()
}
+34 -40
View File
@@ -8,8 +8,6 @@ import (
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
mock "github.com/stretchr/testify/mock"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
)
@@ -26,17 +24,17 @@ func (_m *Searcher) EXPECT() *Searcher_Expecter {
return &Searcher_Expecter{mock: &_m.Mock}
}
// IndexSpace provides a mock function with given fields: rID, uID
func (_m *Searcher) IndexSpace(rID *providerv1beta1.StorageSpaceId, uID *userv1beta1.UserId) error {
ret := _m.Called(rID, uID)
// IndexSpace provides a mock function with given fields: rID
func (_m *Searcher) IndexSpace(rID *providerv1beta1.StorageSpaceId) error {
ret := _m.Called(rID)
if len(ret) == 0 {
panic("no return value specified for IndexSpace")
}
var r0 error
if rf, ok := ret.Get(0).(func(*providerv1beta1.StorageSpaceId, *userv1beta1.UserId) error); ok {
r0 = rf(rID, uID)
if rf, ok := ret.Get(0).(func(*providerv1beta1.StorageSpaceId) error); ok {
r0 = rf(rID)
} else {
r0 = ret.Error(0)
}
@@ -51,14 +49,13 @@ type Searcher_IndexSpace_Call struct {
// IndexSpace is a helper method to define mock.On call
// - rID *providerv1beta1.StorageSpaceId
// - uID *userv1beta1.UserId
func (_e *Searcher_Expecter) IndexSpace(rID interface{}, uID interface{}) *Searcher_IndexSpace_Call {
return &Searcher_IndexSpace_Call{Call: _e.mock.On("IndexSpace", rID, uID)}
func (_e *Searcher_Expecter) IndexSpace(rID interface{}) *Searcher_IndexSpace_Call {
return &Searcher_IndexSpace_Call{Call: _e.mock.On("IndexSpace", rID)}
}
func (_c *Searcher_IndexSpace_Call) Run(run func(rID *providerv1beta1.StorageSpaceId, uID *userv1beta1.UserId)) *Searcher_IndexSpace_Call {
func (_c *Searcher_IndexSpace_Call) Run(run func(rID *providerv1beta1.StorageSpaceId)) *Searcher_IndexSpace_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*providerv1beta1.StorageSpaceId), args[1].(*userv1beta1.UserId))
run(args[0].(*providerv1beta1.StorageSpaceId))
})
return _c
}
@@ -68,14 +65,14 @@ func (_c *Searcher_IndexSpace_Call) Return(_a0 error) *Searcher_IndexSpace_Call
return _c
}
func (_c *Searcher_IndexSpace_Call) RunAndReturn(run func(*providerv1beta1.StorageSpaceId, *userv1beta1.UserId) error) *Searcher_IndexSpace_Call {
func (_c *Searcher_IndexSpace_Call) RunAndReturn(run func(*providerv1beta1.StorageSpaceId) error) *Searcher_IndexSpace_Call {
_c.Call.Return(run)
return _c
}
// MoveItem provides a mock function with given fields: ref, uID
func (_m *Searcher) MoveItem(ref *providerv1beta1.Reference, uID *userv1beta1.UserId) {
_m.Called(ref, uID)
// MoveItem provides a mock function with given fields: ref
func (_m *Searcher) MoveItem(ref *providerv1beta1.Reference) {
_m.Called(ref)
}
// Searcher_MoveItem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MoveItem'
@@ -85,14 +82,13 @@ type Searcher_MoveItem_Call struct {
// MoveItem is a helper method to define mock.On call
// - ref *providerv1beta1.Reference
// - uID *userv1beta1.UserId
func (_e *Searcher_Expecter) MoveItem(ref interface{}, uID interface{}) *Searcher_MoveItem_Call {
return &Searcher_MoveItem_Call{Call: _e.mock.On("MoveItem", ref, uID)}
func (_e *Searcher_Expecter) MoveItem(ref interface{}) *Searcher_MoveItem_Call {
return &Searcher_MoveItem_Call{Call: _e.mock.On("MoveItem", ref)}
}
func (_c *Searcher_MoveItem_Call) Run(run func(ref *providerv1beta1.Reference, uID *userv1beta1.UserId)) *Searcher_MoveItem_Call {
func (_c *Searcher_MoveItem_Call) Run(run func(ref *providerv1beta1.Reference)) *Searcher_MoveItem_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*providerv1beta1.Reference), args[1].(*userv1beta1.UserId))
run(args[0].(*providerv1beta1.Reference))
})
return _c
}
@@ -102,14 +98,14 @@ func (_c *Searcher_MoveItem_Call) Return() *Searcher_MoveItem_Call {
return _c
}
func (_c *Searcher_MoveItem_Call) RunAndReturn(run func(*providerv1beta1.Reference, *userv1beta1.UserId)) *Searcher_MoveItem_Call {
func (_c *Searcher_MoveItem_Call) RunAndReturn(run func(*providerv1beta1.Reference)) *Searcher_MoveItem_Call {
_c.Call.Return(run)
return _c
}
// RestoreItem provides a mock function with given fields: ref, uID
func (_m *Searcher) RestoreItem(ref *providerv1beta1.Reference, uID *userv1beta1.UserId) {
_m.Called(ref, uID)
// RestoreItem provides a mock function with given fields: ref
func (_m *Searcher) RestoreItem(ref *providerv1beta1.Reference) {
_m.Called(ref)
}
// Searcher_RestoreItem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RestoreItem'
@@ -119,14 +115,13 @@ type Searcher_RestoreItem_Call struct {
// RestoreItem is a helper method to define mock.On call
// - ref *providerv1beta1.Reference
// - uID *userv1beta1.UserId
func (_e *Searcher_Expecter) RestoreItem(ref interface{}, uID interface{}) *Searcher_RestoreItem_Call {
return &Searcher_RestoreItem_Call{Call: _e.mock.On("RestoreItem", ref, uID)}
func (_e *Searcher_Expecter) RestoreItem(ref interface{}) *Searcher_RestoreItem_Call {
return &Searcher_RestoreItem_Call{Call: _e.mock.On("RestoreItem", ref)}
}
func (_c *Searcher_RestoreItem_Call) Run(run func(ref *providerv1beta1.Reference, uID *userv1beta1.UserId)) *Searcher_RestoreItem_Call {
func (_c *Searcher_RestoreItem_Call) Run(run func(ref *providerv1beta1.Reference)) *Searcher_RestoreItem_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*providerv1beta1.Reference), args[1].(*userv1beta1.UserId))
run(args[0].(*providerv1beta1.Reference))
})
return _c
}
@@ -136,7 +131,7 @@ func (_c *Searcher_RestoreItem_Call) Return() *Searcher_RestoreItem_Call {
return _c
}
func (_c *Searcher_RestoreItem_Call) RunAndReturn(run func(*providerv1beta1.Reference, *userv1beta1.UserId)) *Searcher_RestoreItem_Call {
func (_c *Searcher_RestoreItem_Call) RunAndReturn(run func(*providerv1beta1.Reference)) *Searcher_RestoreItem_Call {
_c.Call.Return(run)
return _c
}
@@ -233,9 +228,9 @@ func (_c *Searcher_TrashItem_Call) RunAndReturn(run func(*providerv1beta1.Resour
return _c
}
// UpsertItem provides a mock function with given fields: ref, uID
func (_m *Searcher) UpsertItem(ref *providerv1beta1.Reference, uID *userv1beta1.UserId) {
_m.Called(ref, uID)
// UpsertItem provides a mock function with given fields: ref
func (_m *Searcher) UpsertItem(ref *providerv1beta1.Reference) {
_m.Called(ref)
}
// Searcher_UpsertItem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpsertItem'
@@ -245,14 +240,13 @@ type Searcher_UpsertItem_Call struct {
// UpsertItem is a helper method to define mock.On call
// - ref *providerv1beta1.Reference
// - uID *userv1beta1.UserId
func (_e *Searcher_Expecter) UpsertItem(ref interface{}, uID interface{}) *Searcher_UpsertItem_Call {
return &Searcher_UpsertItem_Call{Call: _e.mock.On("UpsertItem", ref, uID)}
func (_e *Searcher_Expecter) UpsertItem(ref interface{}) *Searcher_UpsertItem_Call {
return &Searcher_UpsertItem_Call{Call: _e.mock.On("UpsertItem", ref)}
}
func (_c *Searcher_UpsertItem_Call) Run(run func(ref *providerv1beta1.Reference, uID *userv1beta1.UserId)) *Searcher_UpsertItem_Call {
func (_c *Searcher_UpsertItem_Call) Run(run func(ref *providerv1beta1.Reference)) *Searcher_UpsertItem_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*providerv1beta1.Reference), args[1].(*userv1beta1.UserId))
run(args[0].(*providerv1beta1.Reference))
})
return _c
}
@@ -262,7 +256,7 @@ func (_c *Searcher_UpsertItem_Call) Return() *Searcher_UpsertItem_Call {
return _c
}
func (_c *Searcher_UpsertItem_Call) RunAndReturn(run func(*providerv1beta1.Reference, *userv1beta1.UserId)) *Searcher_UpsertItem_Call {
func (_c *Searcher_UpsertItem_Call) RunAndReturn(run func(*providerv1beta1.Reference)) *Searcher_UpsertItem_Call {
_c.Call.Return(run)
return _c
}
+13 -14
View File
@@ -10,7 +10,6 @@ import (
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
@@ -46,11 +45,11 @@ const (
// Searcher is the interface to the SearchService
type Searcher interface {
Search(ctx context.Context, req *searchsvc.SearchRequest) (*searchsvc.SearchResponse, error)
IndexSpace(rID *provider.StorageSpaceId, uID *user.UserId) error
IndexSpace(rID *provider.StorageSpaceId) error
TrashItem(rID *provider.ResourceId)
UpsertItem(ref *provider.Reference, uID *user.UserId)
RestoreItem(ref *provider.Reference, uID *user.UserId)
MoveItem(ref *provider.Reference, uID *user.UserId)
UpsertItem(ref *provider.Reference)
RestoreItem(ref *provider.Reference)
MoveItem(ref *provider.Reference)
}
// Service is responsible for indexing spaces and pass on a search
@@ -409,7 +408,7 @@ func (s *Service) searchIndex(ctx context.Context, req *searchsvc.SearchRequest,
}
// IndexSpace (re)indexes all resources of a given space.
func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId, uID *user.UserId) error {
func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId) error {
ownerCtx, err := getAuthContext(s.serviceAccountID, s.gatewaySelector, s.serviceAccountSecret, s.logger)
if err != nil {
return err
@@ -456,7 +455,7 @@ func (s *Service) IndexSpace(spaceID *provider.StorageSpaceId, uID *user.UserId)
return nil
}
s.UpsertItem(ref, uID)
s.UpsertItem(ref)
return nil
})
@@ -479,8 +478,8 @@ func (s *Service) TrashItem(rID *provider.ResourceId) {
}
// UpsertItem indexes or stores Resource data fields.
func (s *Service) UpsertItem(ref *provider.Reference, uID *user.UserId) {
ctx, stat, path := s.resInfo(uID, ref)
func (s *Service) UpsertItem(ref *provider.Reference) {
ctx, stat, path := s.resInfo(ref)
if ctx == nil || stat == nil || path == "" {
return
}
@@ -610,8 +609,8 @@ func valueToString(value interface{}) string {
}
// RestoreItem makes the item available again.
func (s *Service) RestoreItem(ref *provider.Reference, uID *user.UserId) {
ctx, stat, path := s.resInfo(uID, ref)
func (s *Service) RestoreItem(ref *provider.Reference) {
ctx, stat, path := s.resInfo(ref)
if ctx == nil || stat == nil || path == "" {
return
}
@@ -622,8 +621,8 @@ func (s *Service) RestoreItem(ref *provider.Reference, uID *user.UserId) {
}
// MoveItem updates the resource location and all of its necessary fields.
func (s *Service) MoveItem(ref *provider.Reference, uID *user.UserId) {
ctx, stat, path := s.resInfo(uID, ref)
func (s *Service) MoveItem(ref *provider.Reference) {
ctx, stat, path := s.resInfo(ref)
if ctx == nil || stat == nil || path == "" {
return
}
@@ -633,7 +632,7 @@ func (s *Service) MoveItem(ref *provider.Reference, uID *user.UserId) {
}
}
func (s *Service) resInfo(uID *user.UserId, ref *provider.Reference) (context.Context, *provider.StatResponse, string) {
func (s *Service) resInfo(ref *provider.Reference) (context.Context, *provider.StatResponse, string) {
ownerCtx, err := getAuthContext(s.serviceAccountID, s.gatewaySelector, s.serviceAccountSecret, s.logger)
if err != nil {
return nil, nil, ""
+1 -1
View File
@@ -128,7 +128,7 @@ var _ = Describe("Searchprovider", func() {
Status: status.NewOK(context.Background()),
Info: ri,
}, nil)
err := s.IndexSpace(&sprovider.StorageSpaceId{OpaqueId: "storageid$spaceid!spaceid"}, user.Id)
err := s.IndexSpace(&sprovider.StorageSpaceId{OpaqueId: "storageid$spaceid!spaceid"})
Expect(err).ShouldNot(HaveOccurred())
})
})
@@ -172,7 +172,7 @@ func (s Service) Search(ctx context.Context, in *searchsvc.SearchRequest, out *s
// IndexSpace (re)indexes all resources of a given space.
func (s Service) IndexSpace(ctx context.Context, in *searchsvc.IndexSpaceRequest, _ *searchsvc.IndexSpaceResponse) error {
return s.searcher.IndexSpace(&provider.StorageSpaceId{OpaqueId: in.SpaceId}, &user.UserId{OpaqueId: in.UserId})
return s.searcher.IndexSpace(&provider.StorageSpaceId{OpaqueId: in.SpaceId})
}
// FromCache pulls a search result from cache