From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

#!/usr/bin/env perl
use strict;
use Mojo::JSON qw(decode_json);
use Mojo::File qw(path);
use File::stat;
use Stor;
$ENV{MOJO_MAX_MESSAGE_SIZE} = 524288000; #the size of message: 500 MB
my $cfg = load_config();
my $statsite = Net::Statsite::Client->new(%{ $cfg->{statsite} });
my $logger = MojoX::Log::Dispatch::Simple->new(
dispatch => Log::Dispatch->new(outputs => $cfg->{log}),
level => 'debug'
);
my $rmq_factory = RmqPublishFactory->new(
uri => $cfg->{rabbitmq_uri},
log => $logger,
);
$rmq_factory->create_mojo_heartbeat();
my $stor = Stor->new(
storage_pairs => $cfg->{storage_pairs},
statsite => $statsite,
basic_auth => $cfg->{basic_auth},
s3_credentials => $cfg->{s3_credentials},
s3_enabled => $cfg->{s3_enabled},
writable_pairs_regex => $cfg->{writable_pairs_regex} // '.*',
rmq_publish_code => $rmq_factory->create(),
);
app->plugin(
CHI => {
default => {
driver => 'Memcached::Fast',
servers => $cfg->{memcached_servers},
l1_cache => { driver => 'Memory', global => 1, max_size => 1024 * 1024 }
}
}
);
app->config(hypnotoad => { clients => $ENV{HYPNOTOAD_CLIENTS} // 100 });
app->log($logger);
start_cleanup_tempdir_task();
get '/' => sub { $stor->about(@_) };
get '/status' => sub { $stor->status(@_) };
get '/:sha' => sub { $stor->get(@_) };
post '/:sha' => sub { $stor->post(@_) };
app->secrets([ $cfg->{secret} ]);
app->start;
sub load_config {
die 'CONFIG_FILE environment variable not set'
if !defined $ENV{CONFIG_FILE};
return decode_json(path($ENV{CONFIG_FILE})->slurp());
}
# cleanup old temp files
sub start_cleanup_tempdir_task {
my $cleanup_tempdir_period = $cfg->{cleanup_tempdir_period} // 60 * 30; #default 30m
Mojo::IOLoop->recurring(
$cleanup_tempdir_period => sub {
path(File::Spec->tmpdir)
->list()
->grep(sub { $_->basename =~ /^mojo\.tmp/ })
->grep(sub { stat($_)->mtime < (time - $cleanup_tempdir_period)})
->each(sub { $_->remove_tree });
}
);
}