Использование Mojo::Pg::Pubsub под hypnotoad
У меня есть таблица с токенами в базе данных Pg, и чтобы не перегружать БД постоянными SELECT, я решил кэшировать токены в оперативной памяти, используя несколько простых помощников mojo (для проверки токена допустимо, удаляя и добавляя токены в такой кэш) в моем приложении.
Я использую Mojo:: Pg:: Pubsub и систему уведомлений Pg (у меня есть триггер, который уведомляет о вставке / удалении токена), чтобы перехватывать события удаления / создания токенов в БД. Все работники запланировали sub в своих ioloops для выполнения SQL DELETE на токенах, которые стали недействительными в DB. С механизмом уведомлений Pg мне нужно получить ситуацию, когда все работники-гипнотизеры будут иметь одинаковый пул токенов в памяти, потому что все они уведомлены о любых изменениях.
Но есть проблема в том, что только 1 рабочий-гипнотад (случайный из пула, каждый раз другой) перехватывает это событие. Я понимаю, что объект Mojo:: Pg, вероятно, становится дублирующим, в то время как рабочие являются вилками. Я также обнаружил, что Mojo:: Server:: Prefork, который находится где-то под капотом приложения mojo, имеет и испускает событие под названием "spawn", которое отмечается в документах как
'Emitted when a worker process is spawned.'
Решение, которое я считаю приемлемым для меня, состоит в том, чтобы подписаться на это событие и воссоздать объект Mojo:: Pg для каждого нового разветвленного работника, но я не могу найти способ получить доступ к объекту сервера, чтобы подписаться на это событие.
Как мне это сделать? А может, я просто что-то делаю не так и есть другие способы решения вышеупомянутой проблемы?
Вот код в моем приложении mojo для работы с БД:
my $pg = connect_mojo($app->config, $app->mode);
$app->helper(pg => sub {
return $pg;
});
$app->helper(db => sub {
return $app->pg->db;
});
А вот код, который отвечает за перехват уведомлений от Pg:
# Postgres notifies about token deletion through it's notification system
$app->pg->pubsub->listen(token_deleted => sub {
my ($this, $token) = @_;
$app->log->info("Notification for deleting token from Pg received: $token");
$app->token_mem->invalidate($token);
});
# Postgres notifies about token creation through it's notification system
$app->pg->pubsub->listen(token_created => sub {
my ($this, $token) = @_;
$app->log->info("Notification for adding token from Pg received: $token");
$app->token_mem->add($token);
});