We have routers which don't support SNMP OIDs for BGP peer status information, so I wrote a fairly simple script. The API call is relatively 'expensive' so I cache the information and want to implement locking so that only a single process ever updates whilst the others reference the cached data.
Overview:
if cache's modification time is less than 60 seconds old, or less th
+an 120 seconds old when it's busy being updated {
load cached hash
else
load information via API and save hash to speed up subsequent look
+ ups
my $cache_ttl = 60;
my $cachefile = '/tmp/mtapi.'.$router.'.cache';
my $lockfile = '/tmp/mtapi.'.$router.'.lock';
my %bgp_peer;
my $cached = 0;
my $modified = (stat($cachefile))[9];
if (defined $modified) {
if (($modified >= (time-$cache_ttl)) || ((-e $lockfile) && ($modifie
+d >= (time-($cache_ttl*2))))) {
if (%bgp_peer = %{lock_retrieve($cachefile)}) { $cached = 1 };
}
}
if ($cached == 0) {
open (LOCK, ">$lockfile");
flock(LOCK, LOCK_EX);
my $api = MikroTik::API->new (
{
host => $router,
username => $api_user,
password => $api_passwd,
use_ssl => 1,
}
);
%bgp_peer = $api->get_by_key('/routing/bgp/peer/print', 'name');
$api->logout();
lock_nstore \%bgp_peer, $cachefile;
chmod 0660, $cachefile;
close LOCK;
unlink $lockfile;
}
I however still see concurrent API logins happening, a lot more than the 'one in a million' that I had assumed...
PS: I'm really not a programmer, so I'd humbly accept any recommendations or suggestions.