UniversityRadioYork / MyRadio

University Radio York's back-end radio management system
https://ury.org.uk/myradio
16 stars 16 forks source link

Attempt to fix podcast caching, yet again #1014

Closed markspolakovs closed 3 years ago

markspolakovs commented 3 years ago

The following paragraph about summarises the cursedness of this issue:

// Pre-emptively write the current state of this object to the cache.
// We need to do this, because the self::getInstance() call above
// poisoned the cache with a NULL $podcast->metadata. So anything
// that tries to read it from now on will hit the cache and get
// an outdated copy. The only remedy is to, effectively, re-poison it
// with the correct value. Yes, this is absolutely cursed.
//
// This is, however, safe: nothing should be able to know the podcast's
// ID until the COMMIT statement afterwards. So by the time it
// has an ID, it will have a freshly baked, correct value waiting
// for it in the cache.
//
// This is not a unique problem; in theory, every ServiceAPI subclass
// is vulnerable.
//
// This is more likely to happen to podcasts than any other type,
// because podcasts are immediately touched by the podcast daemon upon
// creation, which will hold on to the cached instance while it
// converts the file, which may take _a while_ - and then write
// back the copy, poisoning the cache until it expires or gets flushed.
// Putting $this->updateCacheObject() (or even a self::$cache->purge())
// at the end of this method will not help, because by the time this
// function finishes the daemon will have already obtained a reference
// to a poisoned copy.