Repository navigation
director: two ways a record aired twice in a day - #706
Merged
Merged
Conversation
A pick the catalog misses by name is looked up at a provider and ingested, and `discover()` keyed it by the provider's title and lead. That holds for a new row, which the ingest writes with exactly those strings, but not for a copy attached to a work the library already held: the row keeps its own title, `play_history` writes that, and the repeat window was asked about a song it never sees. On 2026-10-20 the model named "Detroit Rock City (Edit)", the strict name match missed the album cut held since August, Spotify answered "Detroit Rock City - Edit", and the record aired at 10:30 and again at 14:08. "Don't Stop Me Now" went the same way against its "Remastered 2011" row. When the ingest reports it created nothing, the pick is now keyed by the existing row's title and lead artist, read through a new `CandidatesRepository.findById`; a row that cannot be read falls back to the provider's strings as before.
`letRepeatsBackIn` gave way whenever a batch came back short of `want`, and short is the ordinary case. On 2026-10-20 a refill wanted fifteen, the rules kept fourteen, and "Pride and Joy" was let back in to make up the number an hour after it aired, with eight records still queued. The resolver did it silently: only the floor told `RepeatWatch`. The window now gives way only when nothing else survived the rules, which is when the running order would actually run dry; then repeats fill the batch to `want`, oldest first, as before. A batch that brings anything keeps the order growing and the director asks again when it runs low. The floor reads the window's ages under the same rule. `PickResolver` now reports the give-way to `RepeatWatch` and the floor no longer does: the resolver decides what airs, a repeat the floor lets back in can still be dropped there for a fresh record, and two writers of one edge flag would put a row on the feed per refill. A caller that asks for no number (a request, a mixed-in record) neither gives way nor reports.
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.
On 2026-10-20 the station aired three records twice inside a 2-day repeat window: Detroit Rock City (10:30 and 14:08), Pride and Joy (07:38 and 09:25, both in Blues Highway), and Don't Stop Me Now (aired 10:00, chosen again at 13:36). There were two separate causes, fixed in one commit each.
A discovered copy was keyed by the provider's title, not the library row's
The model named "Detroit Rock City (Edit)". The strict name match missed the album cut the library has held since August, so the pick went to Spotify, which answered "Detroit Rock City - Edit". The ingest attached that copy to the existing row (
created: false), butdiscover()keyed the pick from the provider's strings. The repeat window was asked aboutkiss:detroit rock city editwhileplay_historywriteskiss:detroit rock city, so nothing could hold it. The feed showed it "discovered" at both 09:52 and 13:36.When the ingest creates nothing, the pick is now keyed by the existing row's title and lead artist (new
CandidatesRepository.findById), falling back to the provider's strings if the row can't be read.The repeat window gave way whenever a batch came back short
At 08:45 a refill wanted 15 and the rules kept 14, so
letRepeatsBackIninPickResolverlet Pride and Joy back in an hour after it aired, with eight records still queued. It did this silently: only the floor reported toRepeatWatch.The window now gives way only when nothing else survived the rules, which is when the running order would actually run dry. Then it fills to
want, oldest first, as before. The floor uses the same rule to decide when to read ages.PickResolvernow reports the give-way and the floor no longer does, since the resolver decides what airs and two writers of one edge flag would flap. Callers that ask for no number (requests, mixed-in records) neither give way nor report.Trade-off: a station whose whole reachable library is inside the window now adds a few records per refill and refills more often, instead of padding with repeats, until nothing fresh is left.
Checks
apps/api: typecheck clean (source and tests), 9919 tests pass, lint and prettier clean on the touched files.docs/internals/programming.mdupdated; a changeset for each commit.