Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncachers #91

Merged
merged 2 commits into from
Jul 3, 2012
Merged

Uncachers #91

merged 2 commits into from
Jul 3, 2012

Conversation

AlexeyDsov
Copy link
Member

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

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

  1. Возникла потребность раскешивать объект после изменения по его старому состоянию (до изменения) и новому. Соотвественно старое состояния неоткуда брать.
  2. В случае если добавления/изменения/удаления объектов происходят внутри транзакции, то после завершения транзакции необходимо выполнить раскешивания. Если это будет сделано до commit'а, то какой-либо параллельный процесс может снова закешить неправильные данные, т.к. в postgres по умолчанию уровень изоляции read commited то как только происходит commit - самое время делать uncache, т.к. изменения будут доступны другим транзакциям.

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

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

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

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

@AlexeyDsov
Copy link
Member Author

По хорошему правильно было бы еще при begin заменять все cache'ы на какой-то внутренний runtimememory кэш. При commit/rollback возвращать обратно тот который был.

@AlexeyDsov
Copy link
Member Author

"Грубо" реализовал описанный выше кейс.

Причина: внутри транзакции может происходить, грубо говоря, всякое. И это всякое не должно попадать в общий кэш и вообще не должно работать с общим кэшом. Соотвественно на время работы внутри транзакции приложению необходимо давать отдельный кэш.


public function __construct(GenericDAO $dao, $id, UncacherBase $workerUncacher)
{
$this->daoMap[get_class($dao)] = array(array($id), $workerUncacher);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Меня смущает момент array(array($id), $workerUncacher);
Мож отдельный класс сделать к примеру CacherMedium::create()->setIds(array $ids)->setWorker($workerUncache)
ммм ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно просто массив заменить на ассоциативный. Типа
array('ids' => array($id), 'workerUncacher' => $workerUncacher);
Честно говоря не нашел пользы от такого вариант для внутренней реализации класса и не сделал. Стоит сделать?

Про отдельный класс не совсем понял, но попробую ответить про использование сеттеров вместо конструктора: сейчас $id и $worker нужно в объект добавить лишь один раз при создании, а потом только объединять анкешеры между собой в один.

@suquant
Copy link
Member

suquant commented Apr 29, 2012

Тесты работают ? )))
Кстати неплохо было-бы дописать тесты чисто на самые изварщенные ситуации ;-)

@AlexeyDsov
Copy link
Member Author

Тесты работают. Большой вредный DaoTest как раз покрывает всякие кэширования. В нем ничего не изменилось, но раз тесты проходят, значит все что было заложено ранее раскешивается когда надо.

Извращенные случаи - это которые именно?

@AlexeyDsov AlexeyDsov mentioned this pull request May 2, 2012
@AlexeyDsov
Copy link
Member Author

Для удобства переребейзиваю, перегруппировываю в один коммит и мержу.
А то сколько можно этой штуке тут висеть.

AlexeyDsov added a commit that referenced this pull request Jul 3, 2012
@AlexeyDsov AlexeyDsov merged commit 7fee176 into onPHP:master Jul 3, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants