Skip to content

Comments

Fix/perf boost#178

Open
CoryChaplin wants to merge 9 commits intokiwiirc:masterfrom
CoryChaplin:fix/perf-boost
Open

Fix/perf boost#178
CoryChaplin wants to merge 9 commits intokiwiirc:masterfrom
CoryChaplin:fix/perf-boost

Conversation

@CoryChaplin
Copy link
Contributor

@CoryChaplin CoryChaplin commented Feb 6, 2026

Quite a big evolution, but it produces a dramatic improvement to the bnc's performance on large networks.
It has been running on my instance for a while now with no issues.
Here's a view on the IOs improvements.

Copie d'écran_20260206_221928

CoryChaplin and others added 3 commits February 6, 2026 22:07
…ions

- Batch upstream IRC lines into single IPC messages to reduce overhead
- Add fast-path for numeric IRC responses and common replyrouter commands
- Direct-stream WHO replies to requesting client, bypassing hooks/replyrouter
- Debounce connection state saves to reduce disk I/O by ~95%
- Flush dirty connection states on graceful shutdown
- Optimize SQLite message queries with covering indexes and pagination
- Add priority write path for user commands in sockets layer
- Fix setNoDelay to only apply to TCP sockets, not WebSockets
- Fix replyrouter array mutation bug causing lost WHO/LIST replies
- Fix shared message object mutation in extended-join hook
- Preserve nick case when restoring buffer state from database

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…liability

- Handle AMQP channel closure with auto-reconnect and retry on send
- Auto-connect networks in KiwiIRC when BNC reports them as connected
- Create query buffers on outgoing PM/NOTICE for proper lastSeen tracking
- Guard lastSeen access in LISTBUFFERS to prevent errors
- Write JOIN/TOPIC synchronously in dumpChannels to fix NAMES ordering
- Flush buffer after dumpChannels for non-bouncer clients
- Don't forward PRIVMSG/NOTICE for channels we've left

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ConnectionIncoming: dumpChannels, sendNames, writeMsg, lastSeen
- ConnectionOutgoing: messageFromUpstream forwarding, nick tracking
- ConnectionState: debounced saves, tempSet, getOrAddBuffer, fromObj nick case
- Hooks: built-in hooks for multi-prefix, userhost-in-names, WHO fast-path
- ReplyRouter: route management, reply forwarding, cleanup
- Add shared test mocks and helpers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ItsOnlyBinary
Copy link
Contributor

Nice work @CoryChaplin
I so far have one suggestion and one question.

I think it would be better if the database cache and mmap sizes where exposed via the config with defaults set lower to better accommodate vps's with low memory sizes and admins who only want to host a few users. (with a comment on suggestions for bigger networks)

As for my question are you sure the priority message system could not result in ordering issues if two commands that are hard to differentiate the results for are sent in quick succession. not sure on a good example but I'm quite sure there is parts of irc-framework that rely on the order of messages to direct responses to the correct cache/request.

CoryChaplin and others added 5 commits February 20, 2026 15:10
…ssages

The batch event handler was registered twice in listenToQueue(), causing
every upstream message to be processed and relayed to clients twice.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…jection

Wrap the retry sendToQueue call in a try-catch so that if the newly
reconnected channel is also closed (race condition), the error is logged
and the message dropped instead of propagating as an unhandledRejection.
When the upstream server supports the echo-message capability, outgoing
PRIVMSG/NOTICE were being stored twice in the history database: once in
clientcommands (immediately on send) and once in upstreamcommands (when
the server echoed the message back). This caused the user's own messages
to appear twice when reloading history in KiwiIRC.

Fix: skip storing in clientcommands when the server supports echo-message,
letting upstreamcommands handle storage via the server echo instead.
…toreMessageLoop

Raw exec('BEGIN')/exec('COMMIT') does not update better-sqlite3's db.inTransaction
property, so the retention cleanup code wrongly assumes no transaction is open and
starts its own write transaction concurrently, causing SQLITE_BUSY.

Replace with db.transaction() which properly tracks transaction state, and make
dataId() synchronous (it had no actual async operations) so it can run inside the
synchronous transaction wrapper. Switch the recursive storeMessageLoop call to
setImmediate to prevent stack overflow on large queues.
Expose cache_size and mmap_size as config options with conservative
defaults (2MB/disabled) for small VPS hosts. Remove MODE from priority
commands to prevent potential response-routing issues with its dual
action/query semantics.
@CoryChaplin
Copy link
Contributor Author

@ItsOnlyBinary Here's an updated version vs your comments, and some production issues fixed.

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.

2 participants