Subject: | Memory Usage [partial fix included] |
Date: | Thu, 15 Nov 2012 15:27:43 -0800 |
To: | bug-Net-Amazon-Glacier [...] rt.cpan.org |
From: | Ted Reed <treed [...] imvu.com> |
It turns out that when you're uploading large files, the memory usage is a
bit extreme. It's basically 7x the size of the file. It seems like this is
because things are passing the payload around byval instead of byref, so
each function call makes another copy. With 100MB payloads, the memory
usage is pretty noticeable. I've got a patch that removes one of the
byvals, but most of the rest can't be fixed without either going into the
libraries that Net::Amazon::Glacier uses or reimplementing their
functionality.
You may or may not want to look into either of those solutions, but I
thought I'd mention it and pass the limited fix along.
HTTP::Request::Common has a special dynamic mode that will stream payloads,
which you might be able to use, but you wouldn't be able to use
Net::Amazon::Signature::V4 with it, as far as I can tell.
We (IMVU) contribute this code specifically under the GPL Version 1 and
Artistic License (Perl) Version 1.
Here is the patch:
--- a/lib/Net/Amazon/Glacier.pm
+++ b/lib/Net/Amazon/Glacier.pm
@@ -150,7 +150,7 @@
'x-amz-sha256-tree-hash' => $th->get_final_hash(),
'x-amz-content-sha256' => sha256_hex( $content ),
],
- $content
+ \$content
);
return 0 unless $res->is_success;
if ( $res->header('location') =~
m{^/([^/]+)/vaults/([^/]+)/archives/(.*)$} ) {
@@ -209,7 +209,7 @@
my $res = $self->_send_receive(
POST => "/-/vaults/$vault_name/jobs",
[ ],
- encode_json($content_raw),
+ \encode_json($content_raw),
);
return 0 unless $res->is_success;
@@ -245,7 +245,7 @@
my $res = $self->_send_receive(
POST => "/-/vaults/$vault_name/jobs",
[ ],
- encode_json($content_raw),
+ \encode_json($content_raw),
);
return 0 unless $res->is_success;
@@ -309,13 +309,15 @@
sub _craft_request {
my ( $self, $method, $url, $header, $content ) = @_;
my $host = 'glacier.'.$self->{region}.'.amazonaws.com';
+ $content //= \undef;
+
my $total_header = [
'x-amz-glacier-version' => '2012-06-01',
'Host' => $host,
'Date' => strftime( '%Y%m%dT%H%M%SZ', gmtime ),
$header ? @$header : ()
];
- my $req = HTTP::Request->new( $method => "https://$host$url",
$total_header, $content);
+ my $req = HTTP::Request->new( $method => "https://$host$url",
$total_header, $$content);
my $signed_req = $self->{sig}->sign( $req );
return $signed_req;
}