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

Timeouts with Docker TTY #136

Open
caarlos0 opened this issue May 10, 2023 · 4 comments
Open

Timeouts with Docker TTY #136

caarlos0 opened this issue May 10, 2023 · 4 comments

Comments

@caarlos0
Copy link
Collaborator

Not sure if it is intended or not, but if you run a docker container with --tty, many queries termenv does timeout.

Minimum reproducible:

// main.go
package main

import (
	"fmt"

	"github.com/muesli/termenv"
)

func main() {
	fmt.Println("BG", termenv.BackgroundColor())
}
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o a .
docker run --rm --tty -v $PWD:/tmp alpine /tmp/a
@johnstcn
Copy link

johnstcn commented Jun 1, 2023

I amended @caarlos0 's example above to write tracing output:

// main.go
package main

import (
	"fmt"
	"os"
	"runtime/trace"

	"github.com/muesli/termenv"
)

func main() {
	f, err := os.OpenFile("/tmp/trace.out", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	trace.Start(f)
	defer trace.Stop()
	fmt.Println("BG", termenv.BackgroundColor())
}
// go.mod
module termenvtimeout

go 1.20

require github.com/muesli/termenv v0.15.1

require (
	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
	github.com/mattn/go-isatty v0.0.17 // indirect
	github.com/mattn/go-runewidth v0.0.14 // indirect
	github.com/rivo/uniseg v0.2.0 // indirect
	golang.org/x/sys v0.6.0 // indirect
)

Running with Docker (in this case, Colima v0.5.5 aarch64) shows the following:

$ GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o a .
$ docker run --rm --tty -v $PWD:/tmp alpine time /tmp/a
^[]11;rgb:14a7/195f/1efb^G^[[116;1RBG #000000
real	0m 5.03s
user	0m 0.00s
sys	0m 0.00s

I'm attaching the resulting trace, but here's the syscall graph for reference:

image

It looks like the culprit is https://github.com/muesli/termenv/blob/master/termenv_unix.go#L142

@korrat
Copy link

korrat commented Jul 26, 2024

I ran into a similar issue with treefmt. When running under lefthook, I observe consistent hangs of almost exactly 10s. Setting the CI=1 environment variable fixes the issue.

After some debugging, I was able to narrow it down to running through PTY.

// client.go
package main

import (
	"os"

	"github.com/muesli/termenv"
)

func main() {
	termenv.NewOutput(os.Stdout)
	termenv.ForegroundColor()
}

// main.go
package main

import (
	"io"
	"os"
	"os/exec"

	"github.com/creack/pty"
)

func main() {
	command := exec.Command("./client")
	p, err := pty.Start(command)
	if err != nil {
		panic(err)
	}

	io.Copy(os.Stdout, p)

	_ = command.Wait()
}

When running, I see a 5s hang:

> gob client.go && time gor main.go
^[]10;rgb:bfbf/bdbd/b6b6^[\^[[68;1Rgo run main.go  0,36s user 0,21s system 10% cpu 5,179 total

I also see garbage output (what looks like escape sequences) on stdout and on the next prompt.

@nikelborm
Copy link

nikelborm commented Nov 15, 2024

Oh, guys, looks like I faced the same problem.
Please take a look at my findings here: charmbracelet/glow#654 (comment)

TLDR

Using unbuffer or script tools which create tty under the hood and printing escape sequences in it causes timeouts.

2 escape sequences causes 10 second of delay:

�]10;?�\�[6n�]11;?�\�[6n

Printing 3 escape sequences causes 15 second of delay:

�]10;?�\�[6n�]11;?�\�[6n�]11;?�\�[6n

@nikelborm
Copy link

Also here is relevant PR: https://github.com/muesli/termenv/pull/57/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants