State::event_log is a plain Vec<String> that is only ever appended to — log_event (relay/src/state.rs:247) pushes, and nothing ever trims. view.rs renders the last 5 entries but leaves the rest in memory for the life of the process.
Today this is low-risk: after #203 the only writers are connect/disconnect failures, TCP send errors, and the XML-export messages, so a session accumulates a handful of entries.
The risk is that it silently becomes a leak the moment anyone adds a log_event call on a hot path. That already happened once — update.rs logged every baton packet and state.rs logged every TCP send. Measured on a harness running at the plugin's 20 Hz with six datarefs enabled, that was ~140 entries/sec (20 baton + 6x20 TCP), which works out to roughly 35MB/hour of retained strings for a panel that only ever shows 5 lines.
Suggested fix: bound the log. Either swap Vec<String> for a VecDeque<String> with a pop_front once it passes a cap, or trim in log_event. A cap in the low hundreds keeps plenty of scrollback headroom while making the structure O(1) in memory regardless of what gets logged.
Raised by @Phlabry in review of #203.
State::event_logis a plainVec<String>that is only ever appended to —log_event(relay/src/state.rs:247) pushes, and nothing ever trims.view.rsrenders the last 5 entries but leaves the rest in memory for the life of the process.Today this is low-risk: after #203 the only writers are connect/disconnect failures, TCP send errors, and the XML-export messages, so a session accumulates a handful of entries.
The risk is that it silently becomes a leak the moment anyone adds a
log_eventcall on a hot path. That already happened once —update.rslogged every baton packet andstate.rslogged every TCP send. Measured on a harness running at the plugin's 20 Hz with six datarefs enabled, that was ~140 entries/sec (20 baton + 6x20 TCP), which works out to roughly 35MB/hour of retained strings for a panel that only ever shows 5 lines.Suggested fix: bound the log. Either swap
Vec<String>for aVecDeque<String>with apop_frontonce it passes a cap, or trim inlog_event. A cap in the low hundreds keeps plenty of scrollback headroom while making the structure O(1) in memory regardless of what gets logged.Raised by @Phlabry in review of #203.