ITADN

Random failure issue with OPDS 2 feed

#679Openbeville 创建于 2026-05-01
B
bevillecommented
[repro_opds_failure.py](https://github.com/user-attachments/files/27283878/repro_opds_failure.py) Hey, I mentioned an issue with the OPDS feed that I brought up in discord, that I probably mischaracterized. I gave Gemini a pass at this, and it seems to have diagnosed it, with the fix _seeming_ to work for me. Here's the report. Take it with a grain of salt, but the suggested fix should be at least innocuous. --- ## Diagnostic Report: OPDS 2.0 Feed Hierarchy Inconsistency ### Symptoms The OPDS 2.0 feeds in Codex exhibit inconsistent behavior across server restarts: 1. **Publisher Feed Regression:** Instead of showing `Publisher -> Series -> Publication`, the feed occasionally skips the Series level and lists all Publications directly under the Publisher. 2. **Series Feed Regression:** Instead of showing `Series -> Publication`, the feed occasionally lists matching Publishers under the Series. This issue is intermittent and can often be "fixed" by restarting the server or reinstalling the app (which triggers a restart), but it eventually returns. ### Root Cause Analysis The issue is caused by **non-deterministic iteration order** of a `frozenset` in the navigation logic. In `codex/codex/views/settings.py`, the browser navigation levels are defined as follows: ```python # FILE: codex/codex/views/settings.py SHOW_KEYS = frozenset({"p", "i", "s", "v"}) ``` ### The Technical Failure Codex calculates the navigation hierarchy by iterating through `SHOW_KEYS`. Because `frozenset` is an unordered collection in Python, the iteration order is determined by Python's internal hash randomization at startup. * **Correct Order (`p, i, s, v`):** The app correctly identifies the hierarchy: Publisher -> Imprint -> Series -> Volume. * **Incorrect Order (e.g., `s, v, p, i`):** If the internal hash table orders "Series" or "Volume" before "Publisher," the navigation logic (specifically in `SharedAnnotationsMixin._get_order_groups`) fails to correctly identify which groups are "children" of the cur rent view. #### Probability Analysis (The "Odds") Because the application uses a set of 4 items, there are **24 possible permutations** (4!) of the navigation order that Python can pick at startup. 1. **Failure Rate:** About **50% of restarts** will result in a "Bad" feed. 2. **The Math:** For the hierarchy to work correctly, Publisher (`p`) must be processed before Series (`s`). In any random shuffle of two items, there is a 50/100 chance that one will appear before the other. 3. **Why Restarting "Fixes" It:** Every restart is a "coin flip." In half the cases, `p` comes before `s` (GOOD), and in the other half, `s` comes before `p` (BAD). This results in the app "losing its place" in the hierarchy, leading to the skipped levels or inverted parent/child relationships reported by users. ### Resolution The collection must be changed from an unordered `frozenset` to an ordered `tuple`. This ensures that the navigation hierarchy is calculated identically across every server instance and restart. ### Permanent Fix Modify `codex/codex/views/settings.py` (Line 31): **Old Code:** ```python SHOW_KEYS = frozenset({"p", "i", "s", "v"}) ``` **New Code:** ```python SHOW_KEYS = ("p", "i", "s", "v") ```
1 条评论