Commit graph

545 commits

Author SHA1 Message Date
d3a5ed33f2
Fix constant garbage collection warnings by monitoring per-process memory
The memory monitoring was incorrectly using total VM memory instead of
per-process memory, causing false positives whenever any process in the
system allocated memory.

Changes:
- Changed memory monitoring to per-process instead of total VM memory
- Reduced thresholds to reasonable per-process values (50MB diff, 100MB total)
- Increased minor GC trigger from 100 to 1000 packets to prevent GC after
  every normal batch

This prevents detecting memory changes from other processes and eliminates
the constant GC warnings while still maintaining proper memory management.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 07:55:28 -05:00
c8bd7980c2
Fix incorrect icon display for "Other SSIDs" on info page
The get_other_ssids function wasn't fetching symbol information from
the database, causing icons to display incorrectly. Updated the query
to include symbol_table_id and symbol_code fields and added them to
the packet struct so render_symbol_html can properly display the icons.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 17:55:42 -05:00
a0c2970b42
Revert to smaller batch sizes to reduce garbage collection frequency
Reduced batch processing parameters to prevent excessive GC:
- Reduced batch_size from 500 to 100 packets
- Adjusted batch_timeout from 2000ms to 1000ms for faster processing
- Reduced max_demand from 750 to 300 to match smaller batches
- Updated hardcoded fallback from 500 to 100 in packet_consumer.ex
- Changed minor GC trigger from 500 to 100 packets to match batch size

These smaller batch sizes were proven to work well in production and
should significantly reduce the frequency of garbage collection while
maintaining good performance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 17:46:04 -05:00
2629589b7f
Fix packet counter accuracy after TRUNCATE operations
The packet counter uses a PostgreSQL sequence that doesn't get reset
when the packets table is truncated, causing inaccurate counts.

This migration:
- Creates an event trigger that automatically resets the packet counter
  sequence when the packets table is truncated
- Adds a manual reset function reset_packet_counter() that can be called
  if needed
- Improves the get_packet_count() function to properly handle when the
  sequence is at 0

After applying this migration, the counter will automatically reset to 0
whenever TRUNCATE is used on the packets table.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 15:25:56 -05:00
2bdad557e9
Optimize memory usage thresholds and VM garbage collection settings
Increased memory thresholds from 10MB/20MB to 500MB/1GB since the server
has 15GB available memory. This prevents constant GC warnings while
maintaining memory safety.

Configured VM garbage collection settings in vm.args.eex:
- Enabled concurrent ports/sockets limit (+Q 65536)
- Set heap sizes and GC parameters optimized for better performance
- Added scheduler and binary heap settings

These changes will reduce unnecessary GC overhead and improve overall
application performance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 15:21:42 -05:00
e41118a243
Remove PacketPipelineSetup to fix application startup crash
The PacketPipelineSetup was attempting to subscribe to a single
PacketConsumer process that doesn't exist. The application uses
PacketConsumerPool which automatically handles subscriptions for
multiple consumer processes, making PacketPipelineSetup redundant
and causing startup failures.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 15:15:06 -05:00
ad2d9c14cf
Fix packet buffer overflow with parallel consumer pool
- Create PacketConsumerPool to run 3 parallel consumers (configurable)
- Increase max_demand from 250 to 750 total (250 per consumer)
- Fix timer management to properly cancel/restart on batch processing
- Configure proper GenStage subscriptions with backpressure control
- Allow unnamed consumers for pool usage

This 3x increase in processing capacity prevents the "Packet buffer full"
warnings by ensuring consumers can keep up with incoming packet rate.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 14:49:52 -05:00
234fc2010f
Implement critical performance optimizations and error handling
This commit introduces several major performance improvements and adds
robust error handling for malformed HTTP requests:

Performance Optimizations:
- Add database migration with BRIN indexes for time-series data and partial
  indexes for recent queries, significantly improving query performance
- Create global StreamingPacketsPubSub system for real-time packet distribution
  with geographic bounds filtering using ETS for fast lookups
- Refactor PacketConsumer to use Stream module for memory-efficient processing,
  preventing memory accumulation during batch operations
- Implement dedicated BroadcastTaskSupervisor pool for async broadcast operations,
  preventing GenServer blocking on I/O
- Increase database connection pool from 25 to 45 (production) and 15 to 30 (dev)
  for better concurrency support

Error Handling:
- Add SentryFilter to prevent Bandit.HTTPError from missing Host headers from
  cluttering Sentry (common with bots/scanners)
- Configure custom 400 Bad Request error handling
- Filter out common bot/scanner paths from error reporting

All changes include comprehensive test coverage following TDD practices.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 18:19:49 -05:00
0d46b89c68
Use Sentry Loader script to handle CORS errors gracefully
- Replaced direct Sentry SDK script tag with the Sentry Loader
- The loader handles CORS/network failures gracefully without breaking the app
- Moved Sentry configuration to use the onLoad callback
- Maintains the same configuration (100% sampling, BrowserTracing, etc.)

The Sentry Loader is a small inline script that:
1. Captures errors immediately (even before SDK loads)
2. Loads the SDK asynchronously
3. Handles load failures gracefully
4. Replays captured errors once SDK is loaded

This approach avoids CORS errors breaking the page load while still
providing error tracking when the SDK is accessible.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:51:21 -05:00
1da12cf665
Remove debug console.log statements from JavaScript files
- Removed all console.log debugging statements from app.js (theme changes, chart rendering)
- Removed all console.log statements from map.ts (map initialization, data processing)
- Removed all console.debug statements from map_helpers.ts
- Removed all console.debug statements from map_fixes.ts
- Kept essential console.error and console.warn statements for error handling
- Reduced bundle size by ~1.4kb

This cleanup removes unnecessary debug output while maintaining error reporting
for production debugging via console.error and Sentry.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:37:05 -05:00
3937dfede7
Configure CSP headers to allow Sentry and CDN scripts
- Added custom content-security-policy to put_secure_browser_headers
- Allowed script sources:
  - https://js.sentry-cdn.com for Sentry SDK
  - https://cdnjs.cloudflare.com for OverlappingMarkerSpiderfier
- Allowed connect sources for Sentry error reporting:
  - https://*.ingest.sentry.io
  - https://*.sentry.io
- Removed custom ContentSecurityPolicy plug in favor of built-in configuration

This properly configures the Content Security Policy to allow all necessary
external resources while maintaining security.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:30:36 -05:00
1c7a1754ee
add sentry-cdn to cors 2025-07-18 15:23:58 -05:00
3c1aa29f82
Configure Sentry to sample 100% of errors and transactions
- Set tracesSampleRate to 1.0 for 100% transaction sampling
- Set sampleRate to 1.0 for 100% error sampling
- Ensures all JavaScript errors and performance data are captured

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:18:19 -05:00
dade93ee5c
Implement Sentry JavaScript integration with proper CSP configuration
- Restored Sentry JavaScript SDK script tag
- Created custom ContentSecurityPolicy plug to allow Sentry domains
- Added proper CSP headers allowing:
  - js.sentry-cdn.com for the SDK
  - *.ingest.sentry.io and *.sentry.io for error reporting
- Initialized Sentry in app.js with:
  - Proper DSN configuration
  - Browser tracing integration
  - 10% transaction sampling rate
  - Filter for non-critical ResizeObserver errors
- Added CSP plug to router pipeline after put_secure_browser_headers

This properly integrates Sentry for JavaScript error tracking while
maintaining security through explicit CSP configuration.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:17:35 -05:00
df436ab55d
Remove frontend Sentry SDK to fix CORS/CSP errors
The frontend Sentry script was causing CORS and Content Security Policy errors.
Since backend error tracking is already configured with Sentry, the frontend
SDK is not essential and has been removed to prevent these errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:14:36 -05:00
420d7ab57b
Remove debug console.log statements for hover handlers
- Removed console.log for "Adding hover handlers for RF packet"
- Removed console.log for "Marker hover start"
- Removed console.log for "Marker hover end"

These were debug statements that are no longer needed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:12:26 -05:00
1a84eb594a
Fix Gleam compilation in Docker builds
- Mark gleam_stdlib and gleeunit with compile: false in mix.exs
- Copy pre-compiled Gleam BEAM files in Dockerfile
- Add explicit mix gleam_compile step before asset compilation
- Ensure priv/gleam directory is included in Docker build

This fixes the "Could not compile :gleam_stdlib" error during deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:11:08 -05:00
18521ed0c1
add sentry 2025-07-18 15:07:53 -05:00
4af0f4a421
Fix JavaScript context binding issues in map component
- Fix "this.__view is undefined" error when calling pushEvent in event handlers
- Bind pushEvent context properly in all marker click and hover handlers
- Replace undefined sendBoundsToServer calls with saveMapState
- Ensure all event handlers check for pushEvent availability and type
- Use .bind(self) to preserve LiveView hook context in callbacks

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 15:05:15 -05:00
468309c70d
Fix potential undefined function error in info page
Add explicit import for Phoenix.HTML to ensure raw/1 function is available.
This helps prevent 'view crashed - undefined' errors that may occur in
certain environments.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:55:01 -05:00
177f0746bc
Fix Gleam compile script error
- Remove gleam@@compile.erl from erlc paths to prevent compilation errors
- Add gleam@@compile.erl to .gitignore
- Update erlc_paths to only include 'src' directory
- This prevents Erlang from trying to compile Gleam's escript files

The error was caused by Erlang trying to compile a shell script that
starts with #\!/usr/bin/env escript as an Erlang source file.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:50:22 -05:00
2e80a720af
Fix LiveView crash by correcting render_symbol_html syntax
Change from {render_symbol_html(...)} to <%= render_symbol_html(...) %>
in three places where APRS symbols are rendered. This fixes the
'view crashed - undefined' error on the info page.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:47:37 -05:00
4b159ba0b7
cleanup 2025-07-18 14:44:52 -05:00
8587a1f948
Improve info page layout with compact map and reorganized cards
- Reduce map height from 400px to 280px to better match position info card
- Add Leaflet CSS/JS includes for map functionality
- Reorganize layout: Position Info and map on top row
- Move Device Info and Other SSIDs to second row in a grid
- Make Other SSIDs table more compact with table-sm class
- Simplify last heard display to show only time ago (remove timestamp)
- Add empty placeholder div to maintain grid layout when no other SSIDs
- Improve responsive layout with lg:col-span-2 and nested grids

The layout now makes better use of horizontal space on larger screens
while maintaining mobile responsiveness.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:43:12 -05:00
05267f20ad
update 2025-07-18 14:16:17 -05:00
05d35150c3
Add build directory to .gitignore
Prevent tracking of Gleam build artifacts and cache files

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:16:03 -05:00
fdcb0b6c5b
Fix Gleam stdlib runtime error in production
- Update gleam_compile task to copy all Gleam stdlib BEAM files
- Add release step to ensure Gleam BEAM files are included in releases
- Copy Gleam stdlib files from both priv/gleam and build directories

This fixes the "UndefinedFunctionError" for gleam@bit_array and other
Gleam stdlib modules in production by ensuring all required BEAM files
are included in the release.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:14:17 -05:00
8cc2cf0a5e
Fix Docker deployment with Gleam integration
- Update gleam_compile task to handle missing mix_gleam/gleam binary
- Add fallback to use pre-compiled BEAM files from priv/gleam
- Include pre-compiled aprsme@encoding.beam for Docker builds
- Update both Dockerfiles to ensure priv/gleam directory exists
- Fix module name filter from "aprs@" to "aprsme@" in fallback logic

This ensures Docker builds work without requiring gleam or mix_gleam
to be installed in the production container.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 14:06:36 -05:00
3e6d73b553
format 2025-07-18 13:59:03 -05:00
00a8f996f4
Add Gleam language integration to Elixir project
- Rename Gleam module from encoding_simple to encoding
- Move Gleam files from src/aprs/ to src/aprsme/ to match project namespace
- Create custom Mix task for Gleam compilation (lib/mix/tasks/gleam_compile.ex)
- Update EncodingUtils to wrap Gleam implementation instead of pure Elixir
- Add Gleam dependencies to mix.exs and configure build paths
- Update Mix aliases to include Gleam compilation in test and compile tasks
- Add Gleam support to GitHub Actions CI workflow with caching
- Add GLEAM_INTEGRATION.md documentation
- All 357 tests passing with Gleam integration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 13:58:21 -05:00
92585ae34f
Fix race condition when zooming map quickly
- Increase debounce time from 300ms to 400ms for bounds updates
- Cancel in-progress historical loading when new bounds are scheduled
- Add stale update detection to skip outdated bounds updates
- Clear timer reference and pending bounds when processing updates
- Add debug logging for cancelled loads and stale updates

This prevents overlapping historical data loads during rapid zoom
changes, eliminating duplicate packets and improving performance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 12:27:46 -05:00
5aae01e66c
add more translations 2025-07-18 11:18:04 -05:00
dadfef8a5b
cleanup 2025-07-18 10:41:26 -05:00
8d5bfe127e
add email 2025-07-18 10:15:09 -05:00
8e04916481
vendor update 2025-07-18 08:39:43 -05:00
af4ab270e2
Replace any types with specific TypeScript types
- Add comprehensive type definitions for Leaflet plugins (heatmap, marker clustering, overlapping marker spiderfier)
- Create event payload interfaces for all LiveView events
- Add marker extension types for APRS-specific properties
- Define Chart.js dataset and configuration types
- Replace 74 instances of 'any' type across all TypeScript files
- Improve type safety for event handlers and state management
- Add proper typing for external library integrations

This refactoring enhances type safety throughout the codebase, making it easier to catch errors at compile time and improving IDE support for autocompletion and refactoring.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-17 17:55:27 -05:00
a31d38ec6a
different trail colors 2025-07-16 09:36:49 -05:00
1d1195ae87
js refactor 2025-07-16 09:23:33 -05:00
566198afa7
clean up warnings 2025-07-16 08:55:46 -05:00
46340e008a
update deps 2025-07-16 08:20:20 -05:00
534bd8df8a
clean up status page 2025-07-15 13:56:01 -05:00
400e444eaa
Fix packet_counters table bloat with sequence-based counter
- Add aggressive autovacuum settings for packet_counters table
- Replace table-based counter with PostgreSQL sequence to eliminate bloat
- Sequences are designed for high-frequency counter operations
- Maintains backward compatibility through get_packet_count() function

The packet_counters table was experiencing severe bloat due to 350K+ updates
on a single row. PostgreSQL sequences avoid this issue entirely.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 13:34:15 -05:00
b4fcd4382e
Fix missing socket return in handle_pending_bounds
The function was sending a message but not returning the socket,
causing an ArgumentError when the result was passed to assign/3.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 11:14:48 -05:00
bf1c8a0b05
Fix Access behavior error in DeviceParser
Replace bracket notation (packet_data[key]) with Map.get/2 to avoid
UndefinedFunctionError when processing ParseError structs that don't
implement the Access behavior.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 11:10:50 -05:00
114514bdfe
Fix missing historical_packets in socket assigns
Add missing :historical_packets initialization to prevent KeyError when
HistoricalLoader tries to access it during zoom-based display handling.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 11:07:05 -05:00
e97d1d6e33
Fix duplicate indexes and missing socket assigns
- Remove duplicate received_at indexes (packets_received_at_asc_idx and packets_recent_hour_idx)
  that were consuming 423 MB, keeping only packets_received_at_idx
- Fix KeyError by initializing missing :all_packets and :visible_packets in socket assigns
- All tests now pass successfully

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 11:01:27 -05:00
c431a45b0b
remove duplicate indexes and fix telemetry metrics 2025-07-15 09:17:30 -05:00
53c88d2262
postgres optimization 2025-07-15 09:06:40 -05:00
0298c8ec91
Revert all packet processing optimizations to fix buffer overflow
- Restored original PacketConsumer implementation from before optimizations
- Reverted to fixed batch size of 50 packets (original value)
- Removed SystemMonitor and InsertOptimizer from application startup
- Restored original config with buffer size 1000 and batch timeout 1000ms
- Removed all dynamic batch sizing and optimization logic

The recent performance optimizations were causing packet buffer overflows
because the dynamic batch sizing was actually slowing down processing.
Reverting to the simpler, working implementation that processes packets
consistently without buffer overflows.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 08:44:26 -05:00
f1d16d656b
Fix packet buffer overflow by reverting dynamic batch sizing
- Increased packet buffer size from 1,000 to 10,000 to handle traffic spikes
- Removed InsertOptimizer dynamic batch sizing that was slowing processing
- Reverted to fixed batch size of 200 for consistent performance
- Simplified insert options to use static configuration
- Added telemetry metrics for buffer overflow and utilization monitoring
- Fixed unused variable warning in packet_consumer.ex

The root cause was the recent performance optimizations that introduced
dynamic batch sizing, which actually degraded performance and caused
the producer buffer to overflow when the consumer couldn't keep up.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 08:25:02 -05:00