Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a comprehensive Server Manager feature that replaces the existing graceful shutdown implementation with a more robust, production-ready HTTP/HTTPS server management system. The new architecture supports managing multiple server instances concurrently with enhanced TLS/HTTPS capabilities.
Key Changes:
- Replaced standalone graceful shutdown module with a centralized server manager that can handle multiple server instances
- Added comprehensive TLS/HTTPS support including certificate files, self-signed certificates, and Let's Encrypt AutoTLS
- Integrated panic recovery middleware with metrics tracking
- Enhanced logger with context extraction for better error tracking
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
pkg/server/manager.go |
Core server manager implementation with graceful shutdown, instance management, and lifecycle control |
pkg/server/interfaces.go |
Defines Manager and Instance interfaces plus Config struct for server configuration |
pkg/server/tls.go |
TLS configuration utilities supporting certificate files, self-signed certs, and Let's Encrypt AutoTLS |
pkg/server/manager_test.go |
Comprehensive tests for server lifecycle, graceful shutdown, health checks, and callbacks |
pkg/server/example_test.go |
Example code demonstrating various usage patterns for the server manager |
pkg/server/README.md |
Updated documentation with new features, configuration options, and deployment examples |
pkg/server/shutdown.go (deleted) |
Removed in favor of integrated manager approach |
pkg/server/shutdown_test.go (deleted) |
Removed in favor of manager tests |
pkg/middleware/panic.go |
New panic recovery middleware with metrics and error tracking integration |
pkg/middleware/panic_test.go |
Tests for panic recovery middleware |
pkg/logger/logger.go |
Enhanced with context extraction for better error tracking with panics |
pkg/metrics/interfaces.go |
Added RecordPanic method to Provider interface |
pkg/metrics/prometheus.go |
Implemented panic tracking metric |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| type serverInstance struct { | ||
| cfg Config | ||
| gracefulServer *gracefulServer | ||
| certFile string // Path to certificate file (may be temporary for self-signed) | ||
| keyFile string // Path to key file (may be temporary for self-signed) | ||
| mu sync.RWMutex | ||
| running bool | ||
| serverErr chan error |
There was a problem hiding this comment.
The serverInstance struct stores paths to potentially temporary certificate files (for self-signed SSL), but these files are never cleaned up when the server stops. This creates a resource leak. Implement cleanup in the Stop method to remove temporary certificate directories.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
|
|
||
| // Return basic TLS config - cert/key will be loaded by ListenAndServeTLS | ||
| tlsConfig := &tls.Config{ | ||
| MinVersion: tls.VersionTLS12, |
There was a problem hiding this comment.
The TLS minimum version should be set to TLS 1.3 instead of TLS 1.2. TLS 1.2 has known vulnerabilities and TLS 1.3 is widely supported. This is a security best practice for new code in 2025.
pkg/server/tls.go
Outdated
| certFile, keyFile, err := saveCertToTempFiles(certPEM, keyPEM) | ||
| if err != nil { | ||
| return nil, "", "", fmt.Errorf("failed to save self-signed certificate: %w", err) | ||
| } | ||
|
|
||
| tlsConfig := &tls.Config{ | ||
| MinVersion: tls.VersionTLS12, | ||
| } | ||
| return tlsConfig, certFile, keyFile, nil |
There was a problem hiding this comment.
The temporary certificate files created for self-signed SSL are never cleaned up. This will accumulate temporary directories in the system temp folder over time, leading to a resource leak. Consider implementing cleanup when the server stops, or use an in-memory certificate instead of writing to disk.
| certFile, keyFile, err := saveCertToTempFiles(certPEM, keyPEM) | |
| if err != nil { | |
| return nil, "", "", fmt.Errorf("failed to save self-signed certificate: %w", err) | |
| } | |
| tlsConfig := &tls.Config{ | |
| MinVersion: tls.VersionTLS12, | |
| } | |
| return tlsConfig, certFile, keyFile, nil | |
| cert, err := tls.X509KeyPair(certPEM, keyPEM) | |
| if err != nil { | |
| return nil, "", "", fmt.Errorf("failed to parse self-signed certificate: %w", err) | |
| } | |
| tlsConfig := &tls.Config{ | |
| MinVersion: tls.VersionTLS12, | |
| Certificates: []tls.Certificate{cert}, | |
| } | |
| // Certificate and key are kept in memory; no temporary files are created. | |
| return tlsConfig, "", "", nil |
| } | ||
|
|
||
| tlsConfig := &tls.Config{ | ||
| MinVersion: tls.VersionTLS12, |
There was a problem hiding this comment.
The TLS minimum version should be set to TLS 1.3 instead of TLS 1.2. TLS 1.2 has known vulnerabilities and TLS 1.3 is widely supported. This is a security best practice for new code in 2025.
| select { | ||
| case s.serverErr <- err: | ||
| default: | ||
| } |
There was a problem hiding this comment.
The error handling for the serverErr channel is problematic. If Start() is called multiple times rapidly, the channel could be closed or have multiple errors written to it, potentially causing a panic or missing errors. Consider using sync.Once for initialization or better synchronization of the error channel lifecycle.
pkg/logger/logger.go
Outdated
| func CatchPanicCallback(location string, cb func(err any)) { | ||
| func CatchPanicCallback(location string, cb func(err any), args ...interface{}) { | ||
| ctx, _ := extractContext(args...) | ||
| if err := recover(); err != nil { |
There was a problem hiding this comment.
This call to 'recover' has no effect because the enclosing function is never called using a defer statement.
There was a problem hiding this comment.
@copilot open a new pull request to apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
…ction Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Implement persistent certificate storage with reuse for self-signed SSL
Fix recover() not working in CatchPanic functions
|
@copilot The go vet is failing: github.com/bitechdev/ResolveSpec/pkg/serverError: pkg/server/manager.go:223:15: impossible type assertion: instance.(*gracefulServer) github.com/bitechdev/ResolveSpec/pkg/server [github.com/bitechdev/ResolveSpec/pkg/server.test]Error: pkg/server/manager.go:223:15: impossible type assertion: instance.(*gracefulServer) The lint as well:
|
Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
Fix impossible type assertion in Remove method
feature: Server Manager