Skip to content

fix(geoip): reuse one City reader across reloads - #175

Merged
Rushaway merged 1 commit into
masterfrom
fix/geoip-reader-reload
Sep 7, 2026
Merged

fix(geoip): reuse one City reader across reloads#175
Rushaway merged 1 commit into
masterfrom
fix/geoip-reader-reload

Conversation

@Rushaway

@Rushaway Rushaway commented Sep 7, 2026

Copy link
Copy Markdown
Member

Problem

!reload produces an error traceback and drops the !ow command (#174):

INFO  | Setup Unloaded 23 commands!
ERROR | Traceback (most recent call last):
  File ".../torchlight/CommandHandler.py", line 52, in Setup
    command = subklass(
  File ".../torchlight/Commands.py", line 425, in __init__
    self.geo_ip = geoip2.database.Reader(f"{self.config_folder}/{self.city_filename}")
  ...
  File ".../maxminddb/__init__.py", line 80, in open_database
    return cast(Reader, _extension.Reader(database, mode))

CommandHandler.Setup() rebuilds every command on each reload, so
OpenWeather.__init__ opened a brand-new geoip2.database.Reader (an mmap of
the ~60 MB City database) every time. #173 added close() on the outgoing
command so that mapping no longer leaked until GC (#55), but re-opening the
database on every !reload is still fragile — and when the open fails, the
exception propagates out of __init__, aborts the command in Setup(), and is
logged as an error. The database is read-only and static; there is no reason to
tear it down and map it again on a config reload.

Fix

  • New torchlight.GeoIP module owns the reader. Only Commands is passed to
    importlib.reload, so a cache in its own module survives !reload.
  • get_city_reader() opens the database once per path and reuses it. It
    reopens only when the file's mtime changes (e.g. after a GeoIP update), closing
    the previous reader once the new one is open. If a reopen fails, it keeps
    serving the previous reader instead of losing GeoIP entirely.
  • OpenWeather no longer raises out of __init__ when the database can't be
    opened: it logs the failure, leaves geo_ip unset, and !ow with no argument
    replies asking for a city instead of crashing. !ow <city> is unaffected.
  • OpenWeather no longer needs its close() override; the generic
    BaseCommand.close() hook from fix(#55): close YoutubeDL, geoip reader, and the audio-clip retain graph #173 stays for future use.

Testing

  • ruff check ., ruff format . --diff, mypy — clean (the two pre-existing
    MyInstants.py mypy errors are unrelated).
  • Standalone test of get_city_reader with a stubbed geoip2.database.Reader
    covering: reuse across calls, surviving repeated Setup() with no file change,
    reopen on mtime change (old reader closed), reopen failure falling back to the
    previous reader, missing file with a warm cache, and first-open failure
    propagating.

Fixes #174

🤖 Generated with Claude Code

`OpenWeather.__init__` opened a fresh `geoip2.database.Reader` every time
`CommandHandler.Setup()` ran. #173 added `close()` on the outgoing command so the
previous mmap of the database no longer leaked until GC (#55), but rebuilding the
reader on every `!reload` is still fragile: any failure to map the file now
aborts command setup with an error traceback in the logs (#174).

Move the reader into a dedicated `torchlight.GeoIP` module (only `Commands` is
reloaded, so the cache survives `importlib.reload`). It is opened once per path
and only reopened when the file on disk actually changes, e.g. after a GeoIP
update; a failed reopen keeps serving the previous reader instead of dropping
GeoIP entirely.

`OpenWeather` no longer raises out of `__init__` when the database cannot be
opened: it logs the error, leaves `geo_ip` unset, and `!ow` without an explicit
location asks the player to name a city instead of crashing.

Bumps VERSION to 1.8.26.

Fixes #174

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Rushaway
Rushaway merged commit 89a923a into master Sep 7, 2026
3 checks passed
@Rushaway
Rushaway deleted the fix/geoip-reader-reload branch September 7, 2026 12:18
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.

bug: Erros logs after reload cmd

1 participant