onPHP/onphp-framework — pull request #91 by AlexeyDsov (2012-04-25 08:25:11+00:00)
Title: Uncachers

По мотивам тикетов о TaggableDaoWorker'е (#85) и о позднем раскешивании в случае транзакции (#84). Собственно код вычленен из #85, т.к. вполне идет на отдельный request.

Проблемы которые надо было решить:

1. Возникла потребность раскешивать объект после изменения по его старому состоянию (до изменения) и новому. Соотвественно старое состояния неоткуда брать.
1. В случае если добавления/изменения/удаления объектов происходят внутри транзакции, то после завершения транзакции необходимо выполнить раскешивания. Если это будет сделано до commit'а, то какой-либо параллельный процесс может снова закешить неправильные данные, т.к. в postgres по умолчанию уровень изоляции [read commited](http://www.postgresql.org/docs/9.1/static/sql-set-transaction.html) то как только происходит commit - самое время делать uncache, т.к. изменения будут доступны другим транзакциям.

Что и как сделано:

1. Добавлен интерфейс UncacherBase с методами merge и uncache.
1. merge подразумевает возможность слияния двух uncacher'ов одного типа в один
1. uncache - вызывает раскешивание
1. Создано несколько Uncacher'ов под интерфейс для различных DAO и DaoWorker'ов, настраиваются они через constructor
1. Добавлен метод в интерфейс BaseDao::getUncacherById - должен возвращать Uncacher для раскешивания конкретного идентификатора.
1. GenericDAO и все DaoWorker'ы теперь реализуют этот интерфейс, а методы uncacheById и uncacheByIds используют теперь getUncacherById и вызывают у него uncache.
1. UncacherGenericDao при вызове метода uncache регистрирует uncacher'ы воркеров в соотвествующих DB, которые в свою очередь либо их сразу вызывают (если вне транзакции), либо собирают с помощью UncachersPool и раскешивают после вызова commit/rollback.

Собственно что меня сейчас смущает в написанном мною:

1. нужно ли в случае транзакции делать раскешивание не только после коммит'а но и сразу как только произошла регистрация uncacher'а в DB (сейчас раскешивание делается дважды, но не уверен что в этом есть толк)
1. нужно ли в случае rollback делать раскешивание
1. на данный момент я сделал для работоспособности только getUncacherById, т.к. именно он вызывается автоматически при изменениях объектов.
1. Названия новых классов/методов обсуждаемы/изменяемы ;)