Clean up and optimize codebase for production readiness

Performance & Reliability Improvements:
- Increase WebSocket buffer sizes from 1KB to 8KB for better throughput
- Increase broadcast channel buffer from 100 to 1000 messages
- Increase Beast message channel buffer from 1000 to 5000 messages
- Increase connection timeout from 10s to 30s for remote receivers

Code Quality Improvements:
- Remove debug output from production code (CPR Debug, Merger Update spam)
- Add MaxDistance constant to replace magic number (999999)
- Clean up comments for better maintainability
- Implement auto-enable for selected aircraft trails

Benefits:
- Much cleaner server logs without debug spam
- Better performance under high aircraft density
- More reliable WebSocket connections with larger buffers
- Improved fault tolerance with increased timeouts

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-24 17:54:17 +02:00
commit 064ba2de71
5 changed files with 23 additions and 23 deletions

View file

@ -191,11 +191,18 @@ class SkyView {
// Update selected aircraft // Update selected aircraft
this.selectedAircraft = icao; this.selectedAircraft = icao;
// Show trail for newly selected aircraft if enabled // Automatically enable selected aircraft trail when an aircraft is selected
if (this.selectedTrailEnabled) { if (!this.selectedTrailEnabled) {
this.aircraftManager.showAircraftTrail(icao); this.selectedTrailEnabled = true;
const selectedTrailCheckbox = document.getElementById('show-selected-trail');
if (selectedTrailCheckbox) {
selectedTrailCheckbox.checked = true;
}
} }
// Show trail for newly selected aircraft
this.aircraftManager.showAircraftTrail(icao);
// DON'T change map view - just open popup like Leaflet expects // DON'T change map view - just open popup like Leaflet expects
if (this.mapManager.map && aircraft.Latitude && aircraft.Longitude) { if (this.mapManager.map && aircraft.Latitude && aircraft.Longitude) {
const marker = this.aircraftManager.aircraftMarkers.get(icao); const marker = this.aircraftManager.aircraftMarkers.get(icao);

View file

@ -73,7 +73,7 @@ func NewBeastClient(source *merger.Source, merger *merger.Merger) *BeastClient {
source: source, source: source,
merger: merger, merger: merger,
decoder: modes.NewDecoder(source.Latitude, source.Longitude), decoder: modes.NewDecoder(source.Latitude, source.Longitude),
msgChan: make(chan *beast.Message, 1000), msgChan: make(chan *beast.Message, 5000),
errChan: make(chan error, 10), errChan: make(chan error, 10),
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
reconnectDelay: 5 * time.Second, reconnectDelay: 5 * time.Second,
@ -146,7 +146,7 @@ func (c *BeastClient) run(ctx context.Context) {
addr := fmt.Sprintf("%s:%d", c.source.Host, c.source.Port) addr := fmt.Sprintf("%s:%d", c.source.Host, c.source.Port)
fmt.Printf("Connecting to Beast stream at %s (%s)...\n", addr, c.source.Name) fmt.Printf("Connecting to Beast stream at %s (%s)...\n", addr, c.source.Name)
conn, err := net.DialTimeout("tcp", addr, 10*time.Second) conn, err := net.DialTimeout("tcp", addr, 30*time.Second)
if err != nil { if err != nil {
fmt.Printf("Failed to connect to %s: %v\n", c.source.Name, err) fmt.Printf("Failed to connect to %s: %v\n", c.source.Name, err)
c.source.Active = false c.source.Active = false

View file

@ -30,6 +30,11 @@ import (
"skyview/internal/modes" "skyview/internal/modes"
) )
const (
// MaxDistance represents an infinite distance for initialization
MaxDistance = float64(999999)
)
// Source represents a data source (dump1090 receiver or similar ADS-B source). // Source represents a data source (dump1090 receiver or similar ADS-B source).
// It contains both static configuration and dynamic status information used // It contains both static configuration and dynamic status information used
// for data fusion decisions and source monitoring. // for data fusion decisions and source monitoring.
@ -431,14 +436,9 @@ func (m *Merger) mergeAircraftData(state *AircraftState, new *modes.Aircraft, so
} }
if updatePosition { if updatePosition {
fmt.Printf("Merger Update %06X: %.6f,%.6f -> %.6f,%.6f\n",
state.Aircraft.ICAO24, state.Latitude, state.Longitude, new.Latitude, new.Longitude)
state.Latitude = new.Latitude state.Latitude = new.Latitude
state.Longitude = new.Longitude state.Longitude = new.Longitude
state.PositionSource = sourceID state.PositionSource = sourceID
} else {
fmt.Printf("Merger Skip %06X: rejected update %.6f,%.6f (current: %.6f,%.6f)\n",
state.Aircraft.ICAO24, new.Latitude, new.Longitude, state.Latitude, state.Longitude)
} }
} }
@ -672,7 +672,7 @@ func (m *Merger) GetAircraft() map[uint32]*AircraftState {
stateCopy.Age = now.Sub(state.LastUpdate).Seconds() stateCopy.Age = now.Sub(state.LastUpdate).Seconds()
// Find closest receiver distance // Find closest receiver distance
minDistance := float64(999999) minDistance := MaxDistance
for _, srcData := range state.Sources { for _, srcData := range state.Sources {
if srcData.Distance > 0 && srcData.Distance < minDistance { if srcData.Distance > 0 && srcData.Distance < minDistance {
minDistance = srcData.Distance minDistance = srcData.Distance

View file

@ -434,9 +434,7 @@ func (d *Decoder) decodeCPRPosition(aircraft *Aircraft) {
oddLon := d.cprOddLon[aircraft.ICAO24] oddLon := d.cprOddLon[aircraft.ICAO24]
d.mu.RUnlock() d.mu.RUnlock()
// Debug: Log CPR input values // CPR input values ready for decoding
fmt.Printf("CPR Debug %s: even=[%.6f,%.6f] odd=[%.6f,%.6f]\n",
aircraft.ICAO24, evenLat, evenLon, oddLat, oddLon)
// CPR decoding algorithm // CPR decoding algorithm
dLat := 360.0 / 60.0 dLat := 360.0 / 60.0
@ -479,12 +477,8 @@ func (d *Decoder) decodeCPRPosition(aircraft *Aircraft) {
// Choose the latitude solution that's closer to the receiver position // Choose the latitude solution that's closer to the receiver position
if distToOdd < distToEven { if distToOdd < distToEven {
aircraft.Latitude = latOdd aircraft.Latitude = latOdd
fmt.Printf("CPR Zone: chose ODD lat=%.6f (dist=%.3f) over EVEN lat=%.6f (dist=%.3f) [ref=%.6f]\n",
latOdd, distToOdd, latEven, distToEven, d.refLatitude)
} else { } else {
aircraft.Latitude = latEven aircraft.Latitude = latEven
fmt.Printf("CPR Zone: chose EVEN lat=%.6f (dist=%.3f) over ODD lat=%.6f (dist=%.3f) [ref=%.6f]\n",
latEven, distToEven, latOdd, distToOdd, d.refLatitude)
} }
// Longitude calculation // Longitude calculation
@ -508,8 +502,7 @@ func (d *Decoder) decodeCPRPosition(aircraft *Aircraft) {
aircraft.Longitude = lon aircraft.Longitude = lon
// Debug: Log final decoded coordinates // CPR decoding completed successfully
fmt.Printf("CPR Result %s: lat=%.6f lon=%.6f\n", aircraft.ICAO24, aircraft.Latitude, aircraft.Longitude)
} }
// nlFunction calculates the number of longitude zones (NL) for a given latitude. // nlFunction calculates the number of longitude zones (NL) for a given latitude.

View file

@ -110,10 +110,10 @@ func NewServer(port int, merger *merger.Merger, staticFiles embed.FS, origin Ori
CheckOrigin: func(r *http.Request) bool { CheckOrigin: func(r *http.Request) bool {
return true // Allow all origins in development return true // Allow all origins in development
}, },
ReadBufferSize: 1024, ReadBufferSize: 8192,
WriteBufferSize: 1024, WriteBufferSize: 8192,
}, },
broadcastChan: make(chan []byte, 100), broadcastChan: make(chan []byte, 1000),
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
} }
} }