Development chronicle — mb572 to mb579 · 3.4dev
The castle has completed one of its most careful rounds of work yet.
This chapter began with a bilingual Seer and an improved operator board. It ended with a deeper redesign of Mediabot’s historical memory: live data and archived records can now work together without forcing MariaDB to materialize enormous combined tables, without silently hiding failures, and without searching an archive that cannot contain the requested information.
No database schema was changed during these rounds.
Mediabot’s horoscope now follows the language of each channel.
A French Common Room receives the historical French reading. English-speaking rooms receive a complete English version covering signs, elements, moods, social climate, projects, advice, warnings, colours and lucky details.
The important part is invisible but deliberate: every French pool has an English twin of exactly the same size.
The same nickname and date therefore produce the same deterministic draw in both languages. The prophecy does not change when it crosses the corridor — only the words on the parchment do.
The partyline .status command now reveals three useful runtime states:
FloodQ: 7 deferred (#miaw:2 UNARMED, #quebec:5)
AchvQ: 3 pending check(s)
Archive: worker running (pid 4242)
Shows deferred IRC output by channel.
The UNARMED marker exposes a queue containing messages without an active drain timer, allowing an operator to spot trouble before users report that the bot has stopped displaying everything.
Shows achievement checks waiting for asynchronous processing.
Shows whether the daily archive is disabled, waiting for its first run, currently running, or completed with an exit code and duration.
The panel reads memory only. A diagnostic command must never become the stall it is meant to diagnose.
Historical counters originally read only the live CHANNEL_LOG table.
Once old records moved to the archive, career views could lose years of history. Message totals, first appearances, ranks, streaks and leaderboard positions could become incomplete.
The first archive-aware pass restored that missing historical vision for:
stats;top;streak;leaderboard.This round also exposed an important design question: how should millions of live and archived rows be queried without bringing the old performance problem back?
The archive-aware view was extended to commands that read message content:
wordcount;last;compat.Old last messages could be found again, vocabulary samples could include long-absent users, and career word statistics no longer stopped at the live retention horizon.
Recent commands such as mood and recap deliberately remained live-only. Their job is to describe the present, not the entire history of the castle.
UNION ALL leaves the Great HallThe initial implementation combined both tables through a derived query:
SELECT * FROM CHANNEL_LOG
UNION ALL
SELECT * FROM archive.CHANNEL_LOG_ARCHIVE
It was compact, but it could be expensive.
For commands using ORDER BY ... LIMIT, MariaDB could still materialize far more rows than the command actually needed. A request for one last message could make the server inspect a very large historical set before returning a single line.
The replacement follows a safer model:
This model now covers the broader career surface, including statistics, rankings, last messages, compatibility, history comparisons, profiles, dashboards, chronologies and milestones.
A nickname split between live and archive records is merged before ranking. Three hundred archived messages plus eight hundred live messages now correctly become one career total of eleven hundred.
Not every archive contains every kind of record.
Mediabot now selects sources by purpose:
content for messages and actions;presence for joins, parts, quits and related events;all when a command genuinely needs both.This matters on Undernet, where presence records may be archived while message content remains entirely live. Content commands no longer search millions of archived presence events that cannot answer the question.
The gather contract was also strengthened:
wordcount all streams text instead of loading an unlimited corpus into memory;public and action, not joins and quits.Filtering message counters introduced a subtle semantic regression.
when and the first seen field of stats promise the first appearance of a nickname, not merely the first time that nickname spoke.
The corrected design uses separate gathers:
public and action only.A user who joined years ago but never spoke can therefore still have a genuine first-seen date and a message total of zero.
The live-source contract was also applied consistently across every archive-aware gather. A live database failure can no longer masquerade as “no history”, “no public activity” or an invented rank.
The final inspection covered a rare but important failure mode.
An archive fetch can fail after some rows have already reached the Perl callback. At that point, the command’s counters have absorbed only part of the archive. The result is neither purely live nor complete.
Mediabot now marks that state as tainted and refuses to display it.
The rule is precise:
The final pass also ensures that stats displays a first-seen date for a nickname that has appeared but has not yet spoken, rather than incorrectly calling that nickname absent from the database.
The archive remains on the same MariaDB server, so millions of historical rows still consume real CPU, disk and buffer-pool resources.
These rounds do not pretend otherwise.
Instead, Mediabot now avoids unnecessary work:
LIMIT and index scans remain effective;The result is not “history for free”. It is history queried deliberately, honestly and with much better control.
The complete local test suite passed after the final mb579 safeguards.
The validation covered:
The Seer now speaks the language of every Common Room.
The Entrance Hall shows what the workers are doing.
The librarians know which shelves to open, the census clerks combine both libraries without losing anyone’s past, and a torn archive scroll is never presented as a complete history.
Mediabot remembers more than before — and, just as importantly, it now knows when a memory can be trusted.
You must be logged in to reply.