Skip to content

Commit

Permalink
fix #784: only ping the host in async apis
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Feb 11, 2021
1 parent d563697 commit 6a6789a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@

This should make it easier to debug crashes in plugin code.

* Fix a regression with the synchronous JavaScript API ([#784](https://github.com/evanw/esbuild/issues/784))

In version 0.8.39, a change was made to avoid dangling esbuild processes when node exits abnormally. The change introduced a periodic ping between the child esbuild process and its host process. If the ping doesn't go through, the child process is able to detect that the host process is no longer there. Then it knows to exit since it's no longer being used.

This caused a problem with the synchronous JavaScript API calls which run the esbuild child process in a single-response mode. The ping message was interpreted as a second response and tripped up the message protocol. Pings are only useful for the asynchronous API calls. Running the pings during synchronous API calls was unintentional. With this release pings are no longer run for synchronous API calls so this regression should be fixed.

## 0.8.43

* Support the `XDG_CACHE_HOME` environment variable ([#757](https://github.com/evanw/esbuild/issues/757))
Expand Down
6 changes: 5 additions & 1 deletion cmd/esbuild/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ func main() {
traceFile := ""
cpuprofileFile := ""
isRunningService := false
sendPings := false

// Do an initial scan over the argument list
argsEnd := 0
Expand Down Expand Up @@ -146,6 +147,9 @@ func main() {
os.Exit(1)
}

case strings.HasPrefix(arg, "--ping"):
sendPings = true

default:
// Strip any arguments that were handled above
osArgs[argsEnd] = arg
Expand All @@ -156,7 +160,7 @@ func main() {

// Run in service mode if requested
if isRunningService {
runService()
runService(sendPings)
return
}

Expand Down
20 changes: 11 additions & 9 deletions cmd/esbuild/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type outgoingPacket struct {
refCount int
}

func runService() {
func runService(sendPings bool) {
service := serviceType{
callbacks: make(map[uint32]responseCallback),
rebuilds: make(map[int]rebuildCallback),
Expand Down Expand Up @@ -83,14 +83,16 @@ func runService() {
// where the host has disappeared and will never send us anything else but
// we incorrectly think we are still needed. In that case we will now try
// to write to stdout and fail, and then know that we should exit.
go func() {
for {
time.Sleep(1 * time.Second)
service.sendRequest(map[string]interface{}{
"command": "ping",
})
}
}()
if sendPings {
go func() {
for {
time.Sleep(1 * time.Second)
service.sendRequest(map[string]interface{}{
"command": "ping",
})
}
}()
}

for {
// Read more data from stdin
Expand Down
2 changes: 1 addition & 1 deletion lib/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export let startService: typeof types.startService = common.longLivedService(()
if (options.worker) throw new Error(`The "worker" option only works in the browser`)
let [command, args] = esbuildCommandAndArgs();
let defaultWD = process.cwd();
let child = child_process.spawn(command, args.concat(`--service=${ESBUILD_VERSION}`), {
let child = child_process.spawn(command, args.concat(`--service=${ESBUILD_VERSION}`, '--ping'), {
windowsHide: true,
stdio: ['pipe', 'pipe', 'inherit'],
});
Expand Down

0 comments on commit 6a6789a

Please sign in to comment.