Commit graph

21 commits

Author SHA1 Message Date
5ef97adaf7
refactor: promote hot-path GenServer state maps to structs
Converts the inline state maps in Is, PacketConsumer, LeaderElection, and
CircuitBreaker into structs with @type t specs. Enforced keys catch typos
on state updates and give dialyzer a concrete type to check against
instead of map() in every handle_* clause.

Is' nested login_params and packet_stats are extracted to their own
modules (Aprsme.Is.LoginParams, Aprsme.Is.PacketStats) rather than
defined inline, per the project's no-nested-modules rule.
2026-04-21 10:26:20 -05:00
31ea64aa6c
perf: reduce per-packet allocations in ingest pipeline
Drop the pre-insert aprs_messages broadcast in Is.dispatch (subscribers
already get a richer payload via postgres:aprsme_packets after insert).
Switch PacketsLive.CallsignView to the per-callsign packets:<CS> topic
so it only receives relevant packets instead of filtering every one.

In PacketConsumer: reuse the received_at stamped in Is.dispatch instead
of calling DateTime.utc_now/0 per packet; drop the duplicate struct_to_map
pass (Is.dispatch already handled it); fold coordinate validation and
Geo.Point construction into set_lat_lon + create_location_geometry so
coords are normalized once; extract device_identifier from the already-
normalized attrs; pre-build the broadcast payload once (identifier pick,
lat/lon aliases, routing callsign) so the async broadcast task no longer
does Map.drop/Map.merge per packet.

Rewrite PacketSanitizer.sanitize_packet / sanitize_data_map with Map.new/2
instead of Enum.reduce + Map.put — one allocation per packet instead of N.

Also compute has_weather in Packet.changeset/2 so direct-changeset inserts
(tests, backfills) populate it the same way the GenStage pipeline does.
2026-04-19 13:33:16 -05:00
f840e8fd34
fix: guard APRS send_message when disconnected 2026-03-22 17:16:44 -05:00
8937c1fb57
fix: handle APRS status DB ownership exits 2026-03-22 16:02:03 -05:00
ac42896271
fix: performance improvements and bug fixes across backend and frontend
Backend:
- Use indexed has_weather boolean for weather queries instead of 6 OR conditions
- Enable gzip compression for static assets
- Re-enable security headers (CSP, X-Frame-Options, X-Content-Type-Options)
- Supervise cleanup task via BroadcastTaskSupervisor instead of Task.start
- Relax IsSupervisor restart limits (5/60s) to survive transient network issues
- Remove dead code: empty cache invalidation block, commented-out logging

Frontend:
- Use callsignIndex for O(1) marker dedup instead of O(n) forEach scan
- Consolidate triple packet loop into single pass in new_packets handler
- Batch trail visualization updates via requestAnimationFrame
- Replace DOM querySelectorAll z-index scan with simple counter
- Only rebuild OMS markers when crossing clustering zoom threshold
- Clean up trail manager on hook destroy
- Remove dead commented-out localStorage code
2026-03-19 12:41:36 -05:00
ac51ecaada
Fix multiple TODO bugs: drain handler, callsign dedup, packet pipeline
- Fix drain_connections missing {:noreply, socket} wrapper
- Fix get_callsign_key to match atom keys from Ecto structs
- Add SpatialPubSub.broadcast_packet to PacketDistributor
- Fix pid_alive? treating {:badrpc, _} as truthy
- Fix SpatialPubSub ensure_float crash on integer strings
- Fix inverted memory calculation in ConnectionMonitor
- Remove dead SSL handler from Is module, consolidate into handle_socket_data
- Remove duplicate packet transformation in Is.dispatch
- Remove invalid placeholders option from insert_all calls
- Change PacketPipelineSupervisor to :rest_for_one strategy
- Update TODO.md marking fixed items
2026-02-19 18:27:25 -06:00
fa89c6d3ca
Add TCP backpressure to packet pipeline
When the PacketProducer buffer crosses 80% capacity, signal Aprsme.Is
to switch its TCP socket to passive mode, leveraging TCP flow control
to slow APRS-IS intake. Resume active mode when buffer drains below 30%.

A 30-second safety valve timer auto-resumes if backpressure gets stuck.
Disconnect/reconnect/terminate paths all clear backpressure state.
2026-02-19 15:31:51 -06:00
509f271eac
Improve packet pipeline reliability, security, and cleanup efficiency
- Fix XSS vulnerability in buildPopupContent fallback (escape callsign/comment)
- Add batch insert retry with individual fallback in PacketConsumer
- Add APRS-IS login response validation (logresp dispatch handler)
- Fix stale generation check bypass in HistoricalLoader
- Replace two-step SELECT+DELETE cleanup with single CTE-based batch DELETE
- Change default packet retention from 365 to 7 days
- Delete MapHelpers (100% duplicate of CoordinateUtils + BoundsUtils)
- Delete AprsIsConnection (dead code, second unused APRS-IS connection)
- Fix InfoMap hook memory leak (store/cancel setTimeout ref)
- Extract singleton loadMapBundle with callback queue in app.js
- Extract @heat_map_max_zoom constant in DisplayManager
- Add telemetry to cleanup worker and PacketProducer buffer overflow
- Track PacketProducer buffer_size as integer for O(1) length checks
- Remove duplicate bounds functions from index.ex
2026-02-19 14:11:48 -06:00
a7d934cb5b
Fix APRS-IS connection, packet pipeline, and cleanup reliability
- Handle login send failure in AprsIsConnection instead of crashing
- Close leaked sockets on login failure in Aprsme.Is (init + reconnect)
- Keep rescheduling keepalive timer when disconnected to prevent permanent loss
- Use supervised BroadcastTaskSupervisor instead of unsupervised Task.start
  for packet broadcasting
- Remove racy Process.alive? check in StreamingPacketsPubSub; send/2 to
  dead PIDs is a no-op, :DOWN monitors handle cleanup
- Add dateline wrapping to SpatialPubSub.point_in_bounds? matching
  StreamingPacketsPubSub behavior
- Add bad_packets table cleanup to PacketCleanupWorker
- Add TODO.md with remaining improvements
2026-02-19 13:34:10 -06:00
6a0c8deb5e
Fix ETS table init, send failure handling, and deployment cleanup
- Initialize :aprsme ETS table in application.ex with message_number
  counter; was missing, causing crash in Is.send_message/1
- Trigger reconnect on gen_tcp.send failure instead of leaking the
  dead socket with active timers
- Remove cluster-only env vars from deployment (POD_IP, POD_NAME,
  POD_NAMESPACE, RELEASE_DISTRIBUTION, RELEASE_NODE) since
  CLUSTER_ENABLED=false
- Remove redundant APRS_PASSCODE secret ref now that APRS_PASSWORD
  is set as plaintext
2026-02-18 12:43:09 -06:00
a5d4f6c16c
Fix cancel_timer crash on nil timer ref during shutdown 2026-02-18 12:24:45 -06:00
751b8a5f1b
improve dialyzer 2025-10-13 10:02:15 -05:00
265c58b9ff
Fix aprs-is variables 2025-10-12 10:32:12 -05:00
566198afa7
clean up warnings 2025-07-16 08:55:46 -05:00
534bd8df8a
clean up status page 2025-07-15 13:56:01 -05:00
aaad32c683
geolocation fix 2025-07-11 13:34:54 -05:00
80602bf2a6
deploy to staging dokku fix 2025-07-11 13:12:52 -05:00
d6417ff16b
more live updates and chart version update 2025-07-04 12:15:38 -05:00
7ef3f59026
parsing improvements 2025-06-28 15:53:27 -05:00
0beb278371
add packet batcher 2025-06-24 15:06:09 -05:00
ce7c50caa1
refactor to use external parser 2025-06-24 14:22:09 -05:00