12/04/2026 18:17pm

JS2GO EP.29 Managing Signals and Processes in Go and JavaScript
#Signal
#Process
#child process
#Go
#JavaScript
Managing signals and processes is essential for controlling an application’s lifecycle. Whether it’s gracefully stopping a server, restarting processes, or handling background jobs, proper signal and process management ensures stability and reliability. In this article, we compare signal and process handling in Go and JavaScript (Node.js), providing code examples and best practices.
1. Process and Signal Management in Node.js (JavaScript)
Node.js provides the process and child_process modules to handle signals and processes.
Capturing Signals (SIGINT, SIGTERM)
process.on('SIGINT', () => {
console.log('Received SIGINT. Exiting gracefully...');
process.exit(0);
});
process.on('SIGTERM', () => {
console.log('Received SIGTERM. Cleaning up...');
process.exit(0);
});
Creating a Child Process
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`Child process exited with code ${code}`);
});
Advantages of Node.js:
✔️ Easy to capture signals and control processes
✔️ Supports asynchronous processes and event-driven patterns
Limitations:
⚠️ Requires event listeners and callbacks
⚠️ Must be careful of zombie processes when spawning child processes
2. Process and Signal Management in Go
Go uses the os and os/signal packages for process and signal handling.
Capturing Signals (SIGINT, SIGTERM)
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println("Received signal:", sig)
fmt.Println("Cleaning up and exiting...")
done <- true
}()
fmt.Println("Waiting for signal...")
<-done
fmt.Println("Exiting program")
}
Creating a Child Process
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("ls", "-lh", "/usr")
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println(string(output))
}
Advantages of Go:
✔️ Type-safe and clear error handling
✔️ Supports signal and process control for backend servers
✔️ Safely manages the process lifecycle
Limitations:
⚠️ More verbose syntax compared to Node.js
⚠️ Requires channels and goroutines to handle signals
3. Best Practices
✔️ Capture signals correctly for graceful shutdown
- Node.js:
process.on('SIGTERM') - Go:
signal.Notify+ channel + goroutine
✔️ Handle child processes carefully
- Use
stdout/stderrto monitor output - Wait for the process to finish (
waitin Go /on('close')in Node.js)
✔️ Logging and Cleanup
- Record events and clean resources (close DB connections, stop server)
- Prevent zombie processes or memory leaks
4. Comparison: Signal & Process Handling JavaScript vs Go
| Feature | JavaScript (Node.js) | Go |
|---|---|---|
| Capture Signals | process.on('SIGINT') | signal.Notify + channel |
| Child Process | child_process.spawn / exec | os/exec.Command |
| Async Handling | Event-driven / callback | Goroutine + channel |
| Logging | console / Winston | fmt / logrus / zap |
| Error Handling | Callback / try/catch | Return error + type-safe |
| Graceful Shutdown | Supported | Supported |
Recommendations:
✔️ Web server / event-driven apps → Node.js for rapid development
✔️ Backend service / concurrent / type-safe → Go for production-critical systems
Next Episode
In EP.30, we will explore Handling HTTP Requests and Responses: JavaScript (Fetch/Express) vs Go (net/http) to compare API creation and professional HTTP management.
Read more
🔵 Facebook: Superdev Academy
🔴 YouTube: Superdev Academy
📸 Instagram: Superdev Academy
🎬 TikTok: https://www.tiktok.com/@superdevacademy?lang=th-TH
🌐 Website: https://www.superdevacademy.com/en