Postgresデータベースから発行されているイベントをリッスンするために、pgAsyncというプラグインでMojoliciousを使用しています。私が現在持っているコードは正常に動作していますが、データベース接続の数は増え続けています。NOTIFY
バックエンド
#!/usr/bin/env perl
use Mojolicious::Lite;
use Mojo::IOLoop;
use Mojolicious::Plugin::PgAsync;
app->secret('awdawdawdawd');
plugin PgAsync => {dbi => ['dbi:Pg:dbname=;host=;port=;', '', '', {AutoCommit => 0, RaiseError => 1}]};
any '/api/listen' => sub {
my $self = shift;
my $saved_tx = $self->tx;
Mojo::IOLoop->stream($self->tx->connection)->timeout(300);
$self->res->headers->add('Content-Type' => 'text/event-stream');
$self->res->headers->add('Cache-Control' => 'no-cache');
$self->res->headers->add('Access-Control-Allow-Origin' => '*');
# required for IE
$self->write(" " x 2048);
$self->write("\nretry: 2000\n\n");
my $drain_cb;
$drain_cb = sub {
my $c = shift;
$c->render_later;
$c->tx($saved_tx);
$c->pg_listen('foo', sub {
my $notify = shift;
my $payload = $notify->{payload};
$c->write("id:1\ndata:$payload\n\n", $drain_cb);
});
};
$self->pg_listen('foo', sub {
my $notify = shift;
my $payload = $notify->{payload};
$self->tx($saved_tx);
$self->write("id:1\ndata:$payload\n\n", $drain_cb);
});
};
app->start;
ご覧のとおり、これを希望どおりに機能させるには、ちょっとしたハッカーを行う必要がありました。 pg_listen
呼び出しのたびにコールバックを未定義にしているように見えました。pg_listen
これは、再度呼び出したときにエラーを引き起こしていました(未定義だったため)。これに対するチェックを追加するために、PgAsync::Db.pmの 34 行目を変更する必要がありました。
$self->callback->($notify_hash, $notify_hash);
->to->
$self->callback->($notify_hash, $notify_hash) if defined $self->callback
フロントエンド
Mojolicious スクリプトからのプッシュ通知をリッスンするために、 EventSourceオブジェクトで JavaScript を使用しています。
var es = new EventSource("/api/listen");
var listener = function (event) {
console.log(event.data);
};
es.addEventListener("open", listener);
es.addEventListener("message", listener);
es.addEventListener("error", listener);
問題
よく見ると、このシステムは、より多くのデータベース接続を継続的に作成しているようです。
何もないところから始めて、1 つのデータベース接続があります。
select count(*) from pg_stat_activity;
morbo と Mojolicious スクリプトを で開始し
DEBUG_PG=1 morbo mojopush.pl
ます。現在、2 つのデータベース接続があります (1 つ目は psql の me で、2 つ目は morbo です)。EventSource オブジェクトを含む Web ページを開きます。
GET
content-type でリクエストを正しく設定text/event-stream
し、接続を開いたままにします。現在、3 つのデータベース接続がありますpsql に入って sendを実行
NOTIFY foo, 'test'
すると、Mojo スクリプトがそれを検出し、Web ページに「test. まだ 3 つの db 接続があります。ページを更新すると、現在 4 つのデータベース接続があります。300 秒の非アクティブ タイムアウトを待つと、さらに別のデータベース接続が作成され、5 つの接続が発生します。
誰かが私を正しい方向に向けるのを助けることができれば、それは非常にありがたいです!