Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@niner
Created July 19, 2017 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niner/b65597abab2bf3ee446a1ce939421a44 to your computer and use it in GitHub Desktop.
Save niner/b65597abab2bf3ee446a1ce939421a44 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl6
use lib:from<Perl5> $*PROGRAM.parent.parent.add('lib').Str;
use ZMS::Configuration:from<Perl5>;
class CacheCleaner {
has $.cache_root;
has $.cache_size;
has %!files;
class CacheEntry {
has Int:D $.size is required handles 'Numeric';
has Instant:D $.age is required;
}
method run() {
self.read-existing;
self.clean-cache;
say "Watching cache $.cache_root with size $.cache_size";
react {
whenever $.cache_root.watch -> $change {
my $path = $change.path.IO;
if $path.e { # could be deleted after event was generated
my $size = $path.s;
if $size { # could get notified before any data is written
%!files{$change.path} = CacheEntry.new(:$size, :age(now));
self.clean-cache;
}
}
}
whenever signal(SIGINT) {
done;
}
}
}
method read-existing() {
for $.cache_root.dir -> $entry {
%!files{$entry.Str} = CacheEntry.new(:size($entry.s), :age($entry.accessed));
}
}
method clean-cache() {
my $total = %!files.values.sum;
return if $total <= $.cache_size;
my @files = %!files.sort({$^a.value.age cmp $^b.value.age}).map: *.key;
while $total > $.cache_size {
my $file = shift @files;
$total -= %!files{$file};
note "Deleting $file age {now - %!files{$file}.age}";
%!files{$file}:delete;
$file.IO.unlink;
}
say "$total bytes in cache";
}
}
my $config = ZMS::Configuration.new;
my $cache_root = $config.get(|<Controller::Static cache_root>).IO;
my $cache_size = $config.get(|<Controller::Static cache_size>);
CacheCleaner.new(:$cache_root, :$cache_size).run;
say "Exiting cleanly.";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment