air-verse / air

☁️ Live reload for Go apps
GNU General Public License v3.0
17.63k stars 802 forks source link

On Windows, application output on stderr not printing immediately; instead prints after app exits #412

Closed shunf4 closed 11 months ago

shunf4 commented 1 year ago

main.go:

package main

import (
        "log"
        "time"
)

func main() {
        log.Printf("abc")
        time.Sleep(3 * time.Second)
}

.air.toml:

root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
  args_bin = []
  bin = "tmp\\main.exe"
  cmd = "go build -o ./tmp/main.exe ."
  delay = 0
  exclude_dir = ["assets", "tmp", "vendor", "testdata"]
  exclude_file = []
  exclude_regex = ["_test.go"]
  exclude_unchanged = false
  follow_symlink = false
  full_bin = ""
  include_dir = []
  include_ext = ["go", "tpl", "tmpl", "html"]
  include_file = []
  kill_delay = "0s"
  log = "build-errors.log"
  rerun = false
  rerun_delay = 500
  send_interrupt = false
  stop_on_error = false

[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  main_only = false
  time = false

[misc]
  clean_on_exit = false

[screen]
  clear_on_rebuild = false
  keep_scroll = true

Current Behaviour

Running air, 2023/04/13 23:54:26 abc does not get printed. Only after hitting Ctrl-C does the log line show.

Expected Behaviour

Log lines on stderr get printed immediately as log.Printf(...) is called, just as when running the application without air.

Abeautifulsnow commented 1 year ago

I have the same problem...

hieunguyena6 commented 1 year ago

any update on this ? I have the same problem :(

makiuchi-d commented 1 year ago

The subcommand's stdin and stderr are output by here: https://github.com/cosmtrek/air/blob/v1.43.0/runner/engine.go#L504-L505 The stderr is not copied until stdin has finished copying. Thus, stderr is outputed after the command is finished and stdin is closed. It might be a good idea to call copy functions in parallel.

On macOS, the subcommand's stdout and stderr are overridden to use os.Stdout and os.Stderr by here: https://github.com/cosmtrek/air/blob/v1.43.0/runner/util_darwin.go#L44-L45 This makes stderr outputs immediately. Incidentally, prepared subcommand's pipes are not used, and the copy functions causing this issue do nothing.

Lastly, on Linux, the subcommand is wrapped by pty, stdout and stderr are merged into the same stream. https://github.com/cosmtrek/air/blob/v1.43.0/runner/util_linux.go#L33 Therefore, subcommand's stderr is output immediately but it is outputed to the stdout of the air.

I don't know which implementation is the best.

Please try arelo, a simpler auto reload tool. It will work well on windows.

go install github.com/makiuchi-d/arelo@latest
arelo -p '**/*.go' -i '**/.*' -- go run .
MatheusKael commented 1 year ago

I came across the same problem. The only way I found to avoid Ctrl-C was by making the air server restart by saving the file again.

ThomasJanUta commented 1 year ago

If your application never exits, because of a running HTTP server for example, you will never see your (error) messages and wonder why your application doesn't work.

This dependency is now broken on Windows. Useless for development unless you never log to stderr.

Reverting to v1.30.0 allows you to develop again: go install github.com/cosmtrek/air@v1.30.0

yg7001 commented 1 year ago

go install github.com/cosmtrek/air@v1.30.0

downgrade resolve many problem!!

the last version, even prevent my app read reply from other web site!!

anton7r commented 1 year ago

This pull request fixes the issue #389

frei-x commented 12 months ago

I also have this problem