Audit: resilience fixes, dead-code cleanup, and dependency overhaul - #46
Merged
Conversation
- media_cache: fix a self-deadlock where update_cache held the non-reentrant cache_lock and then re-acquired it via save_cache_to_disk. Split out a lock-free _write_items_to_disk that the lock holder calls directly. - plexbot: move one-time init out of on_ready (which fires on every gateway reconnect, leaking sessions and re-crawling the cache) into setup_hook. Centralize session teardown in PlexBot.close(), which now stops the gateway before closing the shared Tautulli/TMDB sessions so background tasks can't use (or silently re-open) a closed session. - server_commands: run the git version check off the event loop via asyncio.gather(asyncio.to_thread(...)), once at startup; cancel the presence task on unload instead of closing the shared session; don't treat the "unknown" git sentinel as an outdated version. - media_commands: stop closing the shared Tautulli/TMDB session in cog_unload (the bot owns it now). - plex_data/recommendations: route Tautulli responses through check_response/get_response_data, guard against a null "data" payload, and use stdlib zoneinfo instead of pytz. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Delete the unused utilities.Config class and MyEmbedDescriptionPageSource, and drop unused imports across the package (all caught by ruff F401). - Add a conservative ruff config (F, E9) plus a CI workflow that runs ruff and a compileall smoke test; bump the black/ruff target to py312. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- requirements.txt: declare only directly-imported deps. Add aiohttp and matplotlib (previously only transitive), drop the unused requests/numpy and the bogus "datetime" PyPI package, pin everything to current stable, and add tzdata so stdlib zoneinfo has an IANA database on platforms without a system copy (Windows, slim containers). - Document the real Python floor (3.12, required by nextcord 3.x). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 16, 2026
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.
Outcome of a code-quality audit of the bot. Three logically-scoped commits; each is self-consistent and compiles independently.
1. Resilience & lifecycle fixes (
a9fdf33)MediaCache.update_cacheheld the non-reentrantcache_lockand re-acquired it viasave_cache_to_disk→ latent hang on every post-TTL refresh. Split out a lock-free_write_items_to_diskthe lock holder calls directly.on_ready(fires on every gateway reconnect → leaked aiohttp sessions + re-crawled the cache) intosetup_hook.PlexBot.close()now stops the gateway before closing the shared Tautulli/TMDB sessions so background tasks can't use (or silently re-open) a closed session.git fetchversion check no longer blocks the loop — it runs once at startup viaasyncio.gather(asyncio.to_thread(...)), and the"unknown"failure sentinel is no longer read as "outdated".cog_unload(the bot owns it);ServerCommandscancels its presence task instead.plex_data/recommendationsroute Tautulli responses throughcheck_response/get_response_data(no more crashes when the API returnsNone), guard a nulldatapayload, and use stdlibzoneinfoinstead ofpytz.2. Dead code + linting/CI (
58d7cb9)utilities.Configclass andMyEmbedDescriptionPageSource, plus dead imports across the package.ruffconfig (F,E9) and a CI workflow (ruff +compileallsmoke test); bumped the black/ruff target topy312.3. Dependencies + docs (
c6d8afd)requirements.txt: declare only directly-imported deps — addaiohttp/matplotlib(were only transitive), drop unusedrequests/numpyand the bogusdatetimePyPI package, pin everything to current stable, and addtzdatasozoneinfohas an IANA database on platforms without a system copy.Notes
ruff check .+compileall.plex chart …commands (pandas 3.0 + zoneinfo path) andplex downloading(qBittorrent client bump).last_updatedtimestamp, and consolidating the duplicated duration formatters — flagged as follow-ups.🤖 Generated with Claude Code