From 506ebf13c6e965ea4392151ddc8009b69a4a6f80 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Thu, 14 May 2020 16:57:34 -0700 Subject: [PATCH] DualIndexHashObject can now enqueue saves to prevent repeated-save thrashing --- PBot/DualIndexHashObject.pm | 39 +++++++++++++++++++++++++------------ PBot/PBot.pm | 7 +++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/PBot/DualIndexHashObject.pm b/PBot/DualIndexHashObject.pm index 81873503..48ed47b8 100644 --- a/PBot/DualIndexHashObject.pm +++ b/PBot/DualIndexHashObject.pm @@ -36,6 +36,7 @@ sub initialize { my ($self, %conf) = @_; $self->{name} = $conf{name} // 'Dual Index hash object'; $self->{filename} = $conf{filename} // Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file."); + $self->{save_queue_timeout} = $conf{save_queue_timeout} // 0; $self->{hash} = {}; } @@ -107,20 +108,34 @@ sub save { return; } - $self->{pbot}->{logger}->log("Saving $self->{name} to $filename\n"); + my $subref = sub { + $self->{pbot}->{logger}->log("Saving $self->{name} to $filename\n"); - if (not $self->get_data('$metadata$', '$metadata$', 'update_version')) { - $self->add('$metadata$', '$metadata$', { update_version => PBot::VERSION::BUILD_REVISION }); + if (not $self->get_data('$metadata$', '$metadata$', 'update_version')) { + $self->add('$metadata$', '$metadata$', { update_version => PBot::VERSION::BUILD_REVISION }); + } + + $self->set('$metadata$', '$metadata$', 'name', $self->{name}, 1); + + my $json = JSON->new; + my $json_text = $json->pretty->canonical->utf8->encode($self->{hash}); + + open(FILE, "> $filename") or die "Couldn't open $filename: $!\n"; + print FILE "$json_text\n"; + close FILE; + }; + + if ($self->{save_queue_timeout}) { + # enqueue the save to prevent save-thrashing + $self->{pbot}->{timer}->replace_subref_or_enqueue_event( + $subref, + $self->{save_queue_timeout}, + "save $self->{name}", + ); + } else { + # execute it right now + $subref->(); } - - $self->set('$metadata$', '$metadata$', 'name', $self->{name}, 1); - - my $json = JSON->new; - my $json_text = $json->pretty->canonical->utf8->encode($self->{hash}); - - open(FILE, "> $filename") or die "Couldn't open $filename: $!\n"; - print FILE "$json_text\n"; - close FILE; } sub clear { diff --git a/PBot/PBot.pm b/PBot/PBot.pm index 57c03f6b..68ec9bb4 100644 --- a/PBot/PBot.pm +++ b/PBot/PBot.pm @@ -258,6 +258,13 @@ sub initialize { # give botowner all capabilities $self->{capabilities}->rebuild_botowner_capabilities(); + + # flush all pending save events to disk at exit + $self->{atexit}->register(sub { + $self->{pbot}->{timer}->execute_and_dequeue_event('save *'); + return; + } + ); } sub random_nick {