Skip to content

Commit 1c6e6bd

Browse files
committed
[supervisor] Don't emit DeadlineExceeded if client closes connection (feature flag: supervisor_terminal_no_deadline_exceeded)
1 parent 3f611bf commit 1c6e6bd

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

components/supervisor/pkg/supervisor/supervisor.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"strconv"
3030
"strings"
3131
"sync"
32+
"sync/atomic"
3233
"syscall"
3334
"time"
3435

@@ -336,9 +337,10 @@ func Run(options ...RunOption) {
336337
}
337338
}
338339

340+
terminalNoDeadlineExceeded := watchTerminalNoDeadlineExceeded(ctx, exps, host)
339341
willShutdownCtx, fireWillShutdown := context.WithCancel(ctx)
340342
termMux := terminal.NewMux()
341-
termMuxSrv := terminal.NewMuxTerminalService(termMux)
343+
termMuxSrv := terminal.NewMuxTerminalService(termMux, terminalNoDeadlineExceeded)
342344
termMuxSrv.DefaultWorkdir = cfg.RepoRoot
343345
if cfg.WorkspaceRoot != "" {
344346
termMuxSrv.DefaultWorkdirProvider = func() string {
@@ -582,6 +584,36 @@ func getIDENotReadyShutdownDuration(ctx context.Context, exps experiments.Client
582584
}
583585
}
584586

587+
func watchTerminalNoDeadlineExceeded(ctx context.Context, exps experiments.Client, gitpodHost string) *atomic.Bool {
588+
newBool := func(v bool) *atomic.Bool {
589+
r := atomic.Bool{}
590+
r.Store(v)
591+
return &r
592+
}
593+
if exps == nil {
594+
return newBool(false)
595+
}
596+
597+
value := exps.GetBoolValue(ctx, "supervisor_terminal_no_deadline_exceeded", false, experiments.Attributes{GitpodHost: gitpodHost})
598+
result := newBool(value)
599+
600+
go (func() {
601+
t := time.NewTicker(30 * time.Second)
602+
603+
for {
604+
select {
605+
case <-ctx.Done():
606+
return
607+
case <-t.C:
608+
value := exps.GetBoolValue(ctx, "supervisor_terminal_no_deadline_exceeded", false, experiments.Attributes{GitpodHost: gitpodHost})
609+
result.Store(value)
610+
}
611+
}
612+
})()
613+
614+
return result
615+
}
616+
585617
func isShallowRepository(rootDir string) bool {
586618
cmd := runAsGitpodUser(exec.Command("git", "rev-parse", "--is-shallow-repository"))
587619
cmd.Dir = rootDir

components/supervisor/pkg/terminal/service.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os"
1212
"os/exec"
1313
"path/filepath"
14+
"sync/atomic"
1415
"syscall"
1516
"time"
1617

@@ -26,7 +27,7 @@ import (
2627
)
2728

2829
// NewMuxTerminalService creates a new terminal service.
29-
func NewMuxTerminalService(m *Mux) *MuxTerminalService {
30+
func NewMuxTerminalService(m *Mux, terminalNoDeadlineExceeded *atomic.Bool) *MuxTerminalService {
3031
shell := os.Getenv("SHELL")
3132
if shell == "" {
3233
shell = "/bin/bash"
@@ -36,6 +37,8 @@ func NewMuxTerminalService(m *Mux) *MuxTerminalService {
3637
DefaultWorkdir: "/workspace",
3738
DefaultShell: shell,
3839
Env: os.Environ(),
40+
41+
terminalNoDeadlineExceeded: terminalNoDeadlineExceeded,
3942
}
4043
}
4144

@@ -53,6 +56,8 @@ type MuxTerminalService struct {
5356
DefaultCreds *syscall.Credential
5457
DefaultAmbientCaps []uintptr
5558

59+
terminalNoDeadlineExceeded *atomic.Bool
60+
5661
api.UnimplementedTerminalServiceServer
5762
}
5863

@@ -286,6 +291,9 @@ func (srv *MuxTerminalService) Listen(req *api.ListenTerminalRequest, resp api.T
286291
err = resp.Send(message)
287292
case err = <-errchan:
288293
case <-resp.Context().Done():
294+
if srv.terminalNoDeadlineExceeded.Load() {
295+
return nil
296+
}
289297
return status.Error(codes.DeadlineExceeded, resp.Context().Err().Error())
290298
}
291299
if err == io.EOF {

0 commit comments

Comments
 (0)