IMHO, функциональное реактивное программирование (FRP) в некотором смысле является общим способом решения проблемы недействительности кеша.
Вот почему: устаревшие данные в терминологии FRP называются сбоями . Одна из целей FRP - гарантировать отсутствие сбоев.
FRP более подробно объясняется в этом выступлении «Суть FRP» и в этом SO-ответе .
В разговоре , что Cell
s представляют собой кэшированные Object / Entity и Cell
обновляется , если один из его зависимости обновляется.
FRP скрывает соединительный код, связанный с графом зависимостей, и обеспечивает отсутствие устаревших Cell
s.
Другой способ (отличный от FRP), который я могу придумать, - это обернуть вычисленное значение (типа b
) в некую монаду записи, Writer (Set (uuid)) b
где Set (uuid)
(нотация Haskell) содержит все идентификаторы изменяемых значений, от которых b
зависит вычисленное значение . Итак, uuid
это своего рода уникальный идентификатор, который определяет изменяемое значение / переменную (скажем, строку в базе данных), от которой b
зависит вычисленное значение .
Объедините эту идею с комбинаторами, которые работают с этой монадой записи, и это может привести к какому-то общему решению недействительности кеша, если вы используете эти комбинаторы только для вычисления нового b
. Такие комбинаторы (скажем, специальная версия filter
) принимают монады Writer и (uuid, a)
-s в качестве входных данных, где a
- изменяемые данные / переменная, идентифицируемая с помощью uuid
.
Таким образом, каждый раз, когда вы изменяете «исходные» данные (uuid, a)
(скажем, нормализованные данные в базе данных, из которой b
были вычислены), от которых b
зависит вычисленное значение типа, вы можете аннулировать кеш, который содержит, b
если вы измените любое значение, a
от которого b
зависит вычисленное значение. , потому что на основе Set (uuid)
в Writer Monad вы можете сказать, когда это произойдет.
Таким образом, каждый раз, когда вы изменяете что-то с заданным uuid
, вы транслируете эту мутацию всем кешам, и они аннулируют значения, b
которые зависят от изменяемого значения, идентифицированного с помощью указанного, uuid
потому что монада Writer, в которую b
завернут, может сказать, b
зависит ли это от указанного uuid
или не.
Конечно, это окупается, только если вы читаете гораздо чаще, чем пишете.
Третий, практический подход - использовать материализованные представления в базах данных и использовать их в качестве кэшей. AFAIK они также стремятся решить проблему недействительности. Это, конечно, ограничивает операции, которые связывают изменяемые данные с производными данными.