diff --git a/components/ws-daemon/pkg/cgroup/plugin_process_priority_v2.go b/components/ws-daemon/pkg/cgroup/plugin_process_priority_v2.go index d6a2178b1a6652..f0922a659b7782 100644 --- a/components/ws-daemon/pkg/cgroup/plugin_process_priority_v2.go +++ b/components/ws-daemon/pkg/cgroup/plugin_process_priority_v2.go @@ -9,7 +9,6 @@ import ( "errors" "io/fs" "io/ioutil" - "os" "path/filepath" "regexp" "strconv" @@ -18,7 +17,6 @@ import ( "time" "github.com/shirou/gopsutil/process" - "golang.org/x/xerrors" "github.com/gitpod-io/gitpod/common-go/log" ) @@ -39,6 +37,9 @@ const ( ProcessCodeServerHelper ProcessType = "vscode-server-helper" // ProcessDefault referes to any process that is not one of the above ProcessDefault ProcessType = "default" + + // Repeat applying until this number of processes is reached + NumberOfProcessesToStopApplying = 5 ) type ProcessPriorityV2 struct { @@ -51,21 +52,28 @@ func (c *ProcessPriorityV2) Type() Version { return Version2 } func (c *ProcessPriorityV2) Apply(ctx context.Context, opts *PluginOptions) error { fullCgroupPath := filepath.Join(opts.BasePath, opts.CgroupPath) - _, err := os.Stat(fullCgroupPath) - if errors.Is(err, fs.ErrNotExist) { - return xerrors.Errorf("cannot read cgroup directory %s: %w", fullCgroupPath, err) - } + t := time.NewTicker(10 * time.Second) + defer t.Stop() - go func() { - time.Sleep(10 * time.Second) + for { + select { + case <-ctx.Done(): + return nil + case <-t.C: + } data, err := ioutil.ReadFile(filepath.Join(fullCgroupPath, "workspace", "user", "cgroup.procs")) - if err != nil { + if errors.Is(err, fs.ErrNotExist) { + // the target cgroup/workspace has gone + return nil + } else if err != nil { log.WithField("path", fullCgroupPath).WithError(err).Errorf("cannot read cgroup.procs file") - return + return err } - for _, line := range strings.Split(string(data), "\n") { + var countRunningProcess int + lines := strings.Split(string(data), "\n") + for _, line := range lines { line = strings.TrimSpace(line) if len(line) == 0 { continue @@ -97,14 +105,17 @@ func (c *ProcessPriorityV2) Apply(ctx context.Context, opts *PluginOptions) erro continue } + countRunningProcess += 1 err = syscall.Setpriority(syscall.PRIO_PROCESS, int(pid), priority) if err != nil { log.WithError(err).WithField("pid", pid).WithField("priority", priority).Warn("cannot set process priority") } } - }() - return nil + if countRunningProcess >= NumberOfProcessesToStopApplying { + return nil + } + } } var (