Skip to content

Rolling mode - #21

Draft
kristux wants to merge 7 commits into
ccpgames:masterfrom
kristux:rolling-mode
Draft

Rolling mode#21
kristux wants to merge 7 commits into
ccpgames:masterfrom
kristux:rolling-mode

Conversation

@kristux

@kristux kristux commented Jul 8, 2026

Copy link
Copy Markdown

I created a new type of retention mode. Instead of just purging all the data when we do server mode there is a "rolling mode" which just keeps it at "max messages"

Why?
Currently you can choose between either running loglite until it runs out of memory and crashes or you can enable server mode safe which on multiple occasions has cleared the logs while I'm reading them. It is particularly bad if I'm debugging some error spam

Mostly it is changing a boolean "server mode" to a retention mode. You can either check server mode or rolling mode but not both. You can check nothing and it is unbounded

  • I did upgrade some python code to python 3, honestly I just couldn't be bothered to install python 2
  • I did add some tests as well as a helper for some manual testing

kristux added 7 commits July 7, 2026 21:50
- Replace buffer(msg)[:] with bytes(msg) for ctypes Structure serialization
- Encode string fields to bytes for c_char arrays (machine_name, executable_path, module, channel, message)
- Handle message length in bytes for UTF-8 encoded content
- Add flood_helper.py module for programmatic use
- Add standalone flood script for CLI invocation
- Both support --count N (default 10) plus --host, --port, --severity options
- Helper connects to 127.0.0.1:3273, sends CONNECTION_MESSAGE handshake, then N messages with monotonic sequence numbers in text (msg 0, msg 1, ..., msg N-1)

This allows the Tester to verify rolling-mode eviction, oldest-dropped/newest-kept ordering, and RSS-flat behavior under sustained floods.
Establishes the CMake + ctest wiring for the model layer: a new LogLiteTests
target links abstractlogmodel.cpp and logmodel.cpp (plus logmonitorfilemodel.cpp,
which logmodel.cpp calls into for autosave) against Qt6::Test, registered with
CTest via add_test. One tracer test constructs a fresh LogModel and asserts the
empty-buffer invariant (rowCount() == 1: zero real rows plus the phantom
trailing row).

Qt is built statically here, so LogModel's QPixmap-constructing constructor
needs a real QApplication with a platform plugin, not just the QCoreApplication
QTEST_GUILESS_MAIN provides. The test links and registers the "minimal"
platform plugin explicitly and runs under QT_QPA_PLATFORM=minimal, so it stays
headless without needing a WindowServer connection or a display.

vcpkg.json gains the qtbase "testlib" feature: Qt Test is gated behind that
feature in the vcpkg port, so Qt6::Test does not resolve without it. This adds
no new dependency, only enables an existing module of the already-depended-on
qtbase package.

.gitignore gains a Python section for __pycache__/*.pyc.
Introduce enum class RetentionMode { Unbounded, Server, Rolling } as the single
source of truth for the log buffer retention policy, replacing bool m_serverMode
in LogModel. Server and Unbounded behave exactly as before; Rolling is defined
but inert (behaves like Unbounded, no eviction yet).

Route the existing server-mode enforcement through the enum: readMessages now
calls a protected enforceRetentionPolicy() helper after appending a batch, and
setRetentionMode/setMaxMessages preserve their immediate autosave-and-clear side
effect. Persist the mode as a single integer key retentionMode (0/1/2) and
migrate the legacy serverMode bool on load; a stored retentionMode of 2 routes
straight to Rolling unchanged. The existing Server-mode menu action now drives
the model through the enum.

Add Qt Test equivalence cases proving Server still autosaves and clears at cap,
Unbounded still grows past cap, the legacy key migrates, and Rolling is inert.
Add AbstractLogModel::removeOldestRows to evict the oldest rows from the
front of the buffer with correct begin/endRemoveRows signals over real rows
only, freeing each removed LogMessage. Wire Rolling enforcement in LogModel
so an over-cap buffer is trimmed to exactly maxMessages after each received
batch and immediately on switching into Rolling or lowering the cap.

Decrement the per-head severity statistics for each evicted head so the
statistics stay in step with the buffer contents; continuation rows are not
counted and are skipped, and running counts are left untouched. Extract the
per-message ingest accounting into a protected recordMessage so tests drive
the same statistics path the socket receive loop uses.

Add unit tests: bounded-at-cap, oldest-dropped/newest-kept, continuous
one-in-one-out, trim on mode switch and cap lower, statistics track buffer
with a mixed-severity flood, and multiline straddle safety.
Adds actionRollingMode to the File menu and puts it in a QActionGroup
with actionServerMode using ExclusionPolicy::ExclusiveOptional, so at
most one of the two can be checked (neither checked means Unbounded).
A single handler, retentionModeActionTriggered, resolves whichever
action the group left checked to one RetentionMode and applies it to
the model plus persists it as the single retentionMode setting, so
the menu can never select or restore a combined state.

On startup both actions are set from the same retentionMode value the
model itself loads, so restore lands in exactly one checked state (or
none for Unbounded).
…lood, keep flood_helper.py as canonical

The standalone flood script and flood_helper.py contained identical logic (argparse, severity_map, send loop). Since the module form (python3 -m clients.python.flood_helper) is the verified invocation and requires no sys.path manipulation, the standalone script adds no value. Removing it leaves a single source of truth for the flood functionality.
Remove doc-comments that only restate a self-evident function name and inline
narration of obvious code. Keep and tighten the comments that carry non-obvious
rationale: the phantom sentinel row, the persisted-format stability constraint,
the per-severity eviction invariant, and the UTF-8 byte-length handling.

Comments only, no functional change.
@kristux
kristux marked this pull request as draft July 15, 2026 17:43
@kristux

kristux commented Jul 15, 2026

Copy link
Copy Markdown
Author

There are a few things I'm not happy about when it comes to usability. I'll reopen when I'm done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant