1

我在 Pg 数据库中有一个带有令牌的表,并且为了不使用永久 SELECT 使数据库过载,我决定在我的应用程序中使用几个简单的 mojo 助手(用于检查令牌是否有效、删除令牌并将其添加到此类缓存)将令牌缓存在 RAM 中。

我正在使用 Mojo::Pg::Pubsub 和 Pg 通知系统(我有一个通知令牌插入/删除的触发器)来捕获数据库中删除/创建令牌的事件。所有工作人员都在他们的 ioloops 中安排了子程序,以对数据库中无效的令牌执行 SQL DELETE。使用 Pg 通知机制,我需要得到这样一种情况,即所有 hypnotoad 工作人员将在内存中拥有相同的令牌池,因为他们都通知了任何更改。

但是有一个问题,只有 1 个催眠蟾蜍工人(从池中随机一个,每次不同的一个)捕捉到这个事件。我知道 Mojo::Pg 对象可能会在工人分叉时变得重复。我还发现 Mojo::Server::Prefork 包含在 mojo 应用程序引擎盖下的某处,它具有并发出名为“spawn”的事件,该事件在诸如

'Emitted when a worker process is spawned.'

我认为我可以接受的解决方案是订阅此事件并为每个新的分叉工作人员重新创建 Mojo::Pg 对象,但我找不到访问服务器对象以订阅此事件的方式。

我该怎么做?或者也许我只是做错了什么,还有其他方法可以解决上述问题?

这是我的 mojo 应用程序中用于使用 DB 的代码:

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);
});
4

0 回答 0