Stor

 view release on metacpan or  search on metacpan

lib/Stor.pm  view on Meta::CPAN


        my $mountpoint = qx(df --output=target $storage | tail -n 1);
        chomp $mountpoint;
        die "Storage $storage is not mounted"
            if $mountpoint eq '/';
    }

    $self->statsite->increment('healthcheck.count');

    $c->render(status => 200, text => 'OK');
}

sub get_from_old_storages ($self, $c, $sha) {
    my $tm_cache = time;
    my $path     = $c->chi->get($sha);
    $self->statsite->timing('cache.time', (time - $tm_cache) * 1000);
    if ($path) {
        $self->statsite->increment('cache.hit');
    }
    else {
        $self->statsite->increment('cache.miss');
        my $paths = $self->_lookup($sha);
        return 0 if !@$paths;

        $path = $paths->[0];
        $c->chi->set($sha => $path);
    }

    my $path_stat = $path->stat;
    $c->res->headers->content_length($path_stat->size);
    $c->res->headers->last_modified(time2str($path_stat->mtime));

    my $server_name = $self->_get_server_name_from_path($path, $sha);

    $self->_stream_found_file($c, $path, $server_name);
    $self->statsite->increment("success.get.ok_old.$server_name.count");
    return 1;
}

sub get_from_s3 ($self, $c, $sha) {
    my $hcp_key = $self->_sha_to_filepath($sha);

    my $head_response = $self->bucket->get_key($hcp_key, 'HEAD');
    if (!$head_response) {
        $self->statsite->increment('error.get.not_found_hcp.count');
        return 0;
    }

    my $size = $head_response->{content_length};
    $c->res->headers->content_length($size);
    $c->res->headers->last_modified($head_response->{'last-modified'});

    # get classic HTTP::Request for fetching the file
    my $http_request = Net::Amazon::S3::Request::GetObject->new(
        s3     => $self->bucket->account,
        bucket => $self->bucket->bucket,
        key    => $hcp_key,
        method => 'GET'
    )->http_request;

    # build Mojo request inside transaction for proper streaming
    $c->app->ua->max_response_size(0);
    my $tx = $c->app->ua->build_tx(GET => $http_request->uri->as_string);
    for my $header_key ('authorization', 'date') {
        $tx->req->headers->header($header_key => $http_request->headers->header($header_key));
    }

    $tx->res->content->unsubscribe('read')->on(
        read => sub {
            my (undef, $chunk) = @_;
            if ($chunk) {
                try {
                    $c->write($chunk);
                }
                catch{
                    $c->app->log->warning("Writing chunk failed: $@");
                    $tx->res->content->unsubscribe('read');
                }
            }
        }
    );

    # start downloading
    my $time = time;
    $c->app->ua->start(
        $tx,
        sub {
            $self->statsite->increment('success.get.ok_hcp.count');
            $self->statsite->update('success.get.ok_hcp.size', $size);
            $self->statsite->timing('success.get.ok_hcp.time', (time - $time) * 1000);
        }
    );

    return 1;
}

sub get ($self, $c) {
    my $sha = $c->param('sha');

    $self->statsite->increment('request.get.count');

    try {
        failure::stor::filenotfound->throw({
            msg     => "Given hash '$sha' isn't SHA256",
            payload => { statsite_key => 'error.get.malformed_sha.count' },
        }) if $sha !~ /^[A-Fa-f0-9]{64}$/;

        if (ref $self->rmq_publish_code eq 'CODE')  {
            $self->rmq_publish_code->($sha);
        }

        my $found = 0;
        if ($self->s3_enabled && $self->get_from_s3($c, $sha)) {
            $found = 1;
        }
        elsif ($self->get_from_old_storages($c, $sha)) {
            $found = 1;
        }

        if (!$found) {
            failure::stor::filenotfound->throw(



( run in 0.577 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )