From 3dc744a17e87b328969484ea4d93116004226355 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 6 Nov 2023 22:19:40 +0100 Subject: [PATCH] Communicate through NOTIFY/LISTEN instead of a file. Less delay, obviously. --- bin/sync.pl | 52 ++++++++++++++++++++++++++++++++++++---------------- bin/ws.pl | 5 ++--- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/bin/sync.pl b/bin/sync.pl index 7f101dc..ef07ee7 100644 --- a/bin/sync.pl +++ b/bin/sync.pl @@ -8,13 +8,13 @@ use LWP::UserAgent; use DBI; use POSIX; use Time::HiRes; +use IO::Select; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; use utf8; require '../include/config.pm'; -my $dbh; my @log = (); my %rgb = ( @@ -448,15 +448,24 @@ sub possibly_nag_user { $dbh->do('INSERT INTO users_nagged (userid, last_nag) VALUES (?, CURRENT_TIMESTAMP)', undef, $userid); } +sub db_connect { + my $dbh = DBI->connect("dbi:Pg:dbname=$config::dbname;host=127.0.0.1", $config::dbuser, $config::dbpass, {RaiseError => 1}) + or warn "Could not connect to Postgres: " . DBI->errstr; + if (!defined($dbh)) { + return undef; + } + $dbh->do('LISTEN skvupdate') or return undef; + return $dbh; +} + sub run { + my $dbh = shift; my $total_start = [Time::HiRes::gettimeofday]; @log = (); skv_log("Siste sync startet: " . POSIX::ctime(time)); # Initialize the handles we need for communication. - $dbh = DBI->connect("dbi:Pg:dbname=$config::dbname;host=127.0.0.1", $config::dbuser, $config::dbpass, {RaiseError => 1}) - or die "Could not connect to Postgres: " . DBI->errstr; my $ua = LWP::UserAgent->new('SKVidarLang/1.0'); my $token = get_oauth_bearer_token($dbh, $ua); @@ -755,27 +764,38 @@ sub run { printf "Tok %.0f ms.\n", 1e3 * $elapsed; } +my $dbh = db_connect() or die; if ($#ARGV >= 0 && $ARGV[0] eq '--daemon') { # Start with a single, forced run. - unlink("/srv/skvidar-slack.sesse.net/marker"); - run(); + run($dbh); while (1) { - if (!unlink("/srv/skvidar-slack.sesse.net/marker")) { - unless ($!{ENOENT}) { - warn "/srv/skvidar-slack.sesse.net/marker: $!"; - } + while (!defined($dbh)) { + print STDERR "Database connection lost, reconnecting...\n"; sleep 1; + $dbh = db_connect(); + } + my $s = IO::Select->new($dbh->{pg_socket}); + my @ready = $s->can_read(10.0); + my @exceptions = $s->has_exception(0.0); + + if (scalar @exceptions > 0) { + $dbh->disconnect; + $dbh = undef; next; } - eval { - run(); - }; - if ($@) { - warn "Died with: $@"; + if (scalar @ready > 0) { + eval { + $dbh->{AutoCommit} = 1; + run($dbh); + $dbh->commit; + }; + if ($@) { + warn "Died with: $@"; + $dbh = undef; + } } - $dbh->disconnect; } } else { - run(); + run($dbh); } diff --git a/bin/ws.pl b/bin/ws.pl index 1e4da98..69c7b1d 100644 --- a/bin/ws.pl +++ b/bin/ws.pl @@ -97,8 +97,7 @@ sub ws_cb { sub mark { print STDERR "Marking that a sync is needed.\n"; - open my $fh, ">", "/srv/skvidar-slack.sesse.net/marker"; - close $fh; + $dbh->do('NOTIFY skvupdate'); } sub handle_event { @@ -139,7 +138,7 @@ sub handle_event { if ($type eq 'reaction_added' || $type eq 'reaction_removed') { $dbh->do('INSERT INTO reaction_log (userid, channel, ts, reaction, event_type, event_ts) VALUES (?,?,?,?,?,?)', undef, $user, $channel, $ts, $reaction, $type, $event_ts); - mark(); + mark($dbh); } else { print STDERR "Type is $type (not a reaction added or removed); ignoring.\n"; } -- 2.39.5