Case 1: Panic in an HTTP handler (e.g., a request triggers a panic)
RecoveryMiddleware catches it:
func RecoveryMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
defer func() {
if rec := recover(); rec != nil {
logger.Error("panic recovered", "panic", rec, ...)
c.AbortWithStatusJSON(http.StatusInternalServerError, ...)
}
}()
c.Next()
}
}
✅ The process keeps running — only that one request fails with 500
✅ Other requests continue normally
❌ Container does not restart (no need to)
This is handled correctly in your code
Case 2: Panic in a goroutine (e.g., scheduler, sync, )
Goroutine panics are not caught by RecoveryMiddleware (it only covers HTTP handlers). If a goroutine panics:
The entire process crashes (Go runtime kills the process on unrecovered goroutine panic)
Container exits with non-zero code
With restart: unless-stopped:
✅ Docker detects the container exited
✅ Docker restarts it automatically
✅ Service comes back up in ~5-10 seconds
Case 3: Process killed by OOM (out of memory)
If the VM runs out of memory, the OS kills the process:
Container exits
restart: unless-stopped restarts it
Case 4: Infinite loop / CPU spike (not a crash)
If a bug causes 100% CPU but no crash:
Container stays running
Docker does not restart it (it's still "running")
You'd need a health check to detect this
Your current protection:
Scenario Caught by middleware? Container crashes? Auto-restarts?
Panic in HTTP handler ✅ Yes ❌ No N/A
Panic in goroutine ❌ No ✅ Yes ✅ Yes (with restart policy)
OOM kill N/A ✅ Yes ✅ Yes (with restart policy)
Process segfault N/A ✅ Yes ✅ Yes (with restart policy)
Bottom line: Once you add restart: unless-stopped to <yourService>, the container will auto-restart on any process crash. The RecoveryMiddleware prevents most crashes by catching handler panics. The restart policy is the safety net for everything else.
No comments:
Post a Comment