feat: add membership caching and rest independence#4
Merged
Conversation
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
The repo's rust-toolchain.toml pins channel 1.92.0 but doesn't declare rustfmt or clippy components, so GitHub's actions/checkout image doesn't end up with them and `cargo fmt`/`cargo clippy` fail with "is not installed for the toolchain". Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
If the bot is ever in multiple guilds, presence_update would still populate the presence and membership caches for foreign-guild users. Guard with the same guild_id check used in guild_member_addition / guild_member_removal before doing any cache work. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
dromzeh
reviewed
May 22, 2026
Per review feedback: the bot is only intended to operate in the configured guild. If it ever gets invited elsewhere we'd be paying compute and emitting/caching out-of-scope data. Implement guild_create to immediately leave any non-configured guild, and add guild_delete logging so we notice if the bot is removed from the real guild. This is defense-in-depth on top of the existing guild_id filters in presence_update / guild_member_addition / guild_member_removal. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
dromzeh
requested changes
May 22, 2026
Per review feedback (#4): - Add src/consts.rs with all TTLs, HTTP/WS tunables, Redis bootstrap knobs and an optional DEFAULT_GUILD_ID compile-time fallback so the env var can be omitted in our canonical deployment. - Rename src/redis.rs -> src/cache.rs. The old name shadowed the redis crate import and made the file feel like a Redis driver; it is really a two-tier cache. While there, factor the "try Redis, fall through to memory on Unavailable" pattern into redis_read returning RedisRead::{Hit, Miss, Unavailable} so get / get_membership stop duplicating the dance. - Move membership TTL freshness check onto MembershipEntry. - main.rs consumes all magic numbers from consts; resolve_guild_id encapsulates the GUILD_ID env / DEFAULT_GUILD_ID fallback. No behavioural change beyond DEFAULT_GUILD_ID being a new optional escape hatch (defaults to None == current behaviour). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Per follow-up review: - Hardcode DEFAULT_GUILD_ID to 982385887000272956 (the Antifield guild) so the GUILD_ID env var becomes optional. - Restructure src/consts.rs into nested modules grouped by subject (ttl, http, ws, redis_boot, discord) — call sites now read as ttl::PRESENCE_MS, http::LISTEN_PORT, ws::PING_INTERVAL, etc. - Drop the redundant *_TTL_ suffix on the names since they live inside the `ttl` module. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds membership caching to eliminate repeated Discord REST API calls (~400ms per request) and allows REST endpoints to function independently of active WebSocket connections.
src/redis.rs:
MembershipEntrystruct with TTL trackingget_membership()andset_membership()methods with Redis (6h/5m positive/negative TTL) and in-memory fallbacksrc/discord.rs:
guild_member_additionandguild_member_removalevent handlerspresence_updateto always cache (not just when watcher exists) and opportunistically refresh membership cacheGUILD_MEMBERSintent and plumbguild_idthrough Handlersrc/main.rs:
user_in_server_handlerto check membership cache first, then Discord API fallback with write-throughmemory_cachefield fromWatcherGuard; stop evicting presence on WS closeREADME.md: