Skip to content

Commit

Permalink
Bugfix: Refactor ApplyFuncOnHunts() to not use List() (#3488)
Browse files Browse the repository at this point in the history
This is very slow an leads to a performance bottleneck
  • Loading branch information
scudette committed May 11, 2024
1 parent 30114b1 commit e1cdaf8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
34 changes: 2 additions & 32 deletions services/hunt_dispatcher/hunt_dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ import (
"www.velocidex.com/golang/velociraptor/constants"
"www.velocidex.com/golang/velociraptor/json"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/result_sets"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/services/journal"
"www.velocidex.com/golang/velociraptor/utils"
Expand Down Expand Up @@ -192,37 +191,8 @@ func (self *HuntDispatcher) ProcessUpdate(
// modify the hunts since it is getting a copy of the hunt object.
func (self *HuntDispatcher) ApplyFuncOnHunts(
ctx context.Context, options services.HuntSearchOptions,
cb func(hunt *api_proto.Hunt) error) (res_error error) {

// Page through the hunts table and apply the function on each
// page.
var offset, length int64
length = 1000
rs_options := result_sets.ResultSetOptions{}
for {
hunts, total, err := self.Store.ListHunts(ctx, rs_options, offset, length)
if err != nil {
return err
}

for _, hunt := range hunts {
if options == services.OnlyRunningHunts &&
hunt.State != api_proto.Hunt_RUNNING {
continue
}

err := cb(hunt)
if err != nil {
res_error = err
}
}

offset += int64(len(hunts))
if offset >= total {
break
}
}
return res_error
cb func(hunt *api_proto.Hunt) error) error {
return self.Store.ApplyFuncOnHunts(ctx, options, cb)
}

func (self *HuntDispatcher) GetHunt(
Expand Down
29 changes: 29 additions & 0 deletions services/hunt_dispatcher/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,16 @@ type HuntIndexEntry struct {
}

type HuntStorageManager interface {
// NOTE: This function is very slow! It should only be used by the GUI!
ListHunts(
ctx context.Context,
options result_sets.ResultSetOptions,
offset int64, length int64) ([]*api_proto.Hunt, int64, error)

ApplyFuncOnHunts(
ctx context.Context, options services.HuntSearchOptions,
cb func(hunt *api_proto.Hunt) error) (res_error error)

// Gets a copy of the hunt object
GetHunt(ctx context.Context,
hunt_id string) (*api_proto.Hunt, error)
Expand Down Expand Up @@ -376,3 +381,27 @@ func (self *HuntStorageManagerImpl) Refresh(
// Create an index file.
return self.FlushIndex(ctx)
}

// Applies a callback on all hunts. The callback is not allowed to
// modify the hunts.
func (self *HuntStorageManagerImpl) ApplyFuncOnHunts(
ctx context.Context, options services.HuntSearchOptions,
cb func(hunt *api_proto.Hunt) error) (res_error error) {

self.mu.Lock()
defer self.mu.Unlock()

for _, record := range self.hunts {
if options == services.OnlyRunningHunts &&
record.State != api_proto.Hunt_RUNNING {
continue
}

err := cb(record.Hunt)
if err != nil {
res_error = err
}
}

return res_error
}

0 comments on commit e1cdaf8

Please sign in to comment.