Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reindexing all spaces #9456

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelog/unreleased/index-all-spaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Allow reindexing all spaces

Adds a `--all-spaces` flag to the `ocis search index` command to allow reindexing all spaces at once.

https://github.com/owncloud/ocis/pull/9456
47 changes: 32 additions & 15 deletions ocis-pkg/kql/dictionary_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 12 additions & 11 deletions services/search/pkg/command/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package command

import (
"context"
"errors"
"fmt"
"time"

Expand All @@ -25,22 +26,23 @@ func Index(cfg *config.Config) *cli.Command {
Aliases: []string{"i"},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "space",
Aliases: []string{"s"},
Required: true,
Usage: "the id of the space to travers and index the files of",
Name: "space",
Aliases: []string{"s"},
Usage: "the id of the space to travers and index the files of. This or --all-spaces is required.",
},
&cli.StringFlag{
Name: "user",
Aliases: []string{"u"},
Required: true,
Usage: "the username of the user that shall be used to access the files",
&cli.BoolFlag{
Name: "all-spaces",
Usage: "index all spaces instead. This or --space is required.",
},
},
Before: func(c *cli.Context) error {
Before: func(_ *cli.Context) error {
return configlog.ReturnFatal(parser.ParseConfig(cfg))
},
Action: func(ctx *cli.Context) error {
if ctx.String("space") == "" && !ctx.Bool("all-spaces") {
return errors.New("either --space or --all-spaces is required")
}

traceProvider, err := tracing.GetServiceTraceProvider(cfg.Tracing, cfg.Service.Name)
if err != nil {
return err
Expand All @@ -57,7 +59,6 @@ func Index(cfg *config.Config) *cli.Command {
c := searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)
_, err = c.IndexSpace(context.Background(), &searchsvc.IndexSpaceRequest{
SpaceId: ctx.String("space"),
UserId: ctx.String("user"),
}, func(opts *client.CallOptions) { opts.RequestTimeout = 10 * time.Minute })
if err != nil {
fmt.Println("failed to index space: " + err.Error())
Expand Down
9 changes: 4 additions & 5 deletions services/search/pkg/search/debouncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ 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

mutex sync.Mutex
}

// 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,
Expand All @@ -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()

Expand All @@ -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)
})
}
28 changes: 12 additions & 16 deletions services/search/pkg/search/debouncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -17,57 +16,54 @@ var _ = Describe("SpaceDebouncer", func() {

callCount atomic.Int32

userId = &user.UserId{
OpaqueId: "user",
}
spaceid = &sprovider.StorageSpaceId{
OpaqueId: "spaceid",
}
)

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)
}
})
})

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())
}, "200ms").Should(Equal(2))
})

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))

Expand Down
Loading