gleam-lang / gleam

⭐️ A friendly language for building type-safe, scalable systems!
https://gleam.run
Apache License 2.0
17.26k stars 715 forks source link

Watchexec halts because of gleam build (escript) sends SIGTTOU #2710

Closed ad-ops closed 1 month ago

ad-ops commented 5 months ago

Version

Gleam 1.0.0 Archlinux & MacOs (M2)

Problem

escript build step sends SIGTTOU after compilation is done causing watchexec to hang.

watchexec -r -e gleam -- gleam run

Workaround

Using fd .gleam | entr -r -s 'gleam run' works fine, but I would rather use watchexec (which some got to work?). If there are any good work arounds I would be glad to use them.

Reproduce

FROM alpine:edge

RUN apk update && \
    apk upgrade && \
    apk add gleam watchexec strace

RUN watchexec --version
RUN gleam --version

WORKDIR app
RUN gleam new hello
WORKDIR hello
RUN gleam run

CMD ["watchexec", "-r", "--stop-signal", "SIGKILL", "--stop-timeout", "5", "-e", "gleam", "-E", "GLEAM_LOG=debug", "strace -e 'trace=!all' gleam run"]
lpil commented 5 months ago

OK so it looks like -r the flag to make watchexec restart the program when file change, but due to SIGTTOU being emitted it does not work. Is that right?

Why does it do that? Is that intended behaviour or a bug in watchexec?

ad-ops commented 5 months ago

I don’t know much about the underlying issues, but from what I could read the SIGTTOU is sent when a background process tries to write output which it is not allowed to.

It looks like you can disable this with stty -tostop, but I had no success running it. I was hoping that maybe there was something that could be set with the erlang build scripts to prevent them from not writing (but it seems to have no issues with the GLEAM_LOG set.

Not the most important issue, but I saw many had the issue on discord so if it is not fixable maybe it is possible have a workaround or documentation.

lpil commented 5 months ago

It would be really good to get this working, for sure! I'm keen to understand why it is that watchexec stops when this happens.

How did you work out that it's SIGTTOU and that is causing the issue?

ad-ops commented 5 months ago

I think it is working as intended, but I wished it could be ignored (should be possible, but I am having some skill-issues:-) ).

I did not try it with different shells (I ran it with zsh) and I will see if using others might help.

http://curiousthing.org/sigttin-sigttou-deep-dive-linux

ad-ops commented 5 months ago

It didn't work to change shell, but it works to remove the INPUT (even if there is no input being sent). This is the comment that hinted to this solution.

# works as expected
watchexec -r -e gleam -- gleam run </dev/null
lpil commented 5 months ago

Oh interesting! I must admit I don't understand what is happening here at all. Perhaps we could try not passing stdin to escript and see if that changes anything?

ad-ops commented 5 months ago

I am also out of my depth with this, but I do like to watch code for changes:-).

I tried to remove this line, but it made no difference. I just ran the command by itself and still get the same error, so it is somehow disconnected from gleam.

watchexec -r --stop-signal SIGKILL --stop-timeout 5 -e gleam -- escript /Users/myuser/ws/gleam/hello/build/dev/erlang/hello/_gleam_artefacts/gleam@@compile.erl --lib /Users/myuser/ws/gleam/hello/build/dev/erlang --out /Users/adrian.opsahl/ws/gleam/hello/build/dev/erlang/hello/ebin /Users/myuser/ws/gleam/hello/build/dev/erlang/hello/_gleam_artefacts/hello.erl

I don't know enough erlang to understand if there is anything in the code or how escript works. Still the workaround is good enough for me.