Skip to content

Commit

Permalink
Cap our read buffers before AIO file operations to 1MB, this will pre…
Browse files Browse the repository at this point in the history
…vent

memory over-use on systems with slow disks for PUT, or buffered upload temp
files. Assuming you system is fast enough to keep up with the writes this
will not harm upload speeds.
  • Loading branch information
hachi committed Apr 22, 2010
1 parent ca24e0a commit 6dbf223
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGES
@@ -1,3 +1,8 @@
-- Cap our read buffers before AIO file operations to 1MB, this will prevent
memory over-use on systems with slow disks for PUT, or buffered upload temp
files. Assuming you system is fast enough to keep up with the writes this
will not harm upload speeds.

1.75: 2010-04-02

-- Stop doubleforking on daemonization. Seems useless and triggered a bug
Expand Down
9 changes: 9 additions & 0 deletions lib/Perlbal/ClientHTTP.pm
Expand Up @@ -247,6 +247,9 @@ sub handle_put_chunked {
return;
}

# Reading too far ahead of our AIO subsystem will cause us to buffer it in memory.
$self->watch_read(0) if $self->{read_ahead} >= 1024 * 1024; # arbitrary
# ->put_writeout clears {read_ahead}, so we run it after we need that
$self->put_writeout if $self->{read_ahead} >= 8192; # arbitrary
},
on_disconnect => sub {
Expand Down Expand Up @@ -333,6 +336,9 @@ sub event_read_put {
$self->{content_length_remain} -= $clen;

if ($self->{content_length_remain}) {
# Reading too far ahead of our AIO subsystem will cause us to buffer it in memory.
$self->watch_read(0) if $self->{read_ahead} >= 1024 * 1024; # arbitrary
# ->put_writeout clears {read_ahead}, so we run it after we need that
$self->put_writeout if $self->{read_ahead} >= 8192; # arbitrary
} else {
# now, if we've filled the content of this put, we're done
Expand Down Expand Up @@ -426,6 +432,9 @@ sub put_writeout {
$self->{read_buf} = [];
$self->{read_ahead} = 0;

# After copying out and clearing the buffer, turn reads back on again to fill up another buffer.
$self->watch_read(1) if $self->{content_length_remain} || $self->{chunked_upload_state};

# okay, file is open, write some data
$self->{put_in_progress} = 1;

Expand Down
10 changes: 8 additions & 2 deletions lib/Perlbal/ClientProxy.pm
Expand Up @@ -1084,6 +1084,8 @@ sub continue_buffered_upload {
# write data to disk
sub buffered_upload_update {
my Perlbal::ClientProxy $self = shift;
# Reading too far ahead of our AIO subsystem will cause us to buffer it in memory.
$self->watch_read(0) if $self->{read_ahead} >= 1024 * 1024; # arbitrary
return if $self->{is_writing};
return unless $self->{is_buffering} && $self->{read_ahead};

Expand Down Expand Up @@ -1124,9 +1126,13 @@ sub buffered_upload_update {
}

# at this point, we want to do some writing
my $bref = shift(@{$self->{read_buf}});
my $bref = \join("", map { $$_ } @{$self->{read_buf}});
$self->{read_buf} = []; # clear these out
$self->{read_ahead} = 0;
my $len = length $$bref;
$self->{read_ahead} -= $len;

# After copying out and clearing the buffer, turn reads back on again to fill up another buffer.
$self->watch_read(1) if $self->{content_length_remain} || $self->{chunked_upload_state};

# so at this point we have a valid filename and file handle and should write out
# the buffer that we have
Expand Down

0 comments on commit 6dbf223

Please sign in to comment.