Использование 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);
});

0 ответов

Другие вопросы по тегам