[Net-IMAP-Server] having issues with managing memory for large accounts

Alex Vandiver alexmv at bestpractical.com
Wed May 25 16:09:49 EDT 2011


On Wed, 2011-05-25 at 10:53 -0700, Sachin Sebastian wrote:
> Thanks Alex. I'll try them out. Any code sample will be of great help.

It's possibly something that should get rolled into the default
Net::IMAP::Server::Mailbox class, thinking about it -- though it would
mean doing all loading through ->poll, which is a slight change from how
we suggest you do it now.  Anyways, I've included the (totally untested)
relevant bits below.
 - Alex


---------8<---------------
package Net::IMAP::Server::Mailbox::Lazy;

use warnings;
use strict;

use Net::IMAP::Server::Message;
use base 'Net::IMAP::Server::Mailbox';

__PACKAGE__->mk_accessors( qw/is_loaded/ );

=head1 NAME

Net::IMAP::Server::Mailbox::Lazy - Drop messages from memory when possible

=head1 METHODS

=head2 is_loaded

Returns true if the mailbox currently has messages populated in it

=head2 poll

Notes that there are messages in the mailbox.  Subclasses should likely
override this to populate messages into the mailbox, paying attention to
L</is_loaded> -- if it is false, this is the initial load of the
mailbox.  If it is true, it is a later poll looking for updates to the
mailbox.  After their own logic, subclasses should be sure to call
C<$self->SUPER::poll> such that L</is_loaded> is set correctly.

=cut

sub poll {
    my $self = shift;
    $self->is_loaded(1);
    $self->SUPER::poll();
}

=head2 status

Make sure that messages get purged from memory after STATUS operation if
there are no other connections with this mailbox open.

=cut

sub status {
    my $self = shift;
    my $loaded = defined $self->is_loaded;
    my %keys = $self->SUPER::status(@_);
    $self->unload unless $is_loaded;
    return %keys;
}

=head2 close

When a session closes a mailbox, call L</unload> unless there are other
active connections to the mailbox.

=cut

sub close {
    my $self = shift;
    return unless $Net::IMAP::Server::Server->connection;
    my @concurrent = grep { $_ ne $Net::IMAP::Server::Server->connection }
        Net::IMAP::Server->concurrent_mailbox_connections($self);
    $self->unload unless @concurrent;
}

=head2 unload

Called when no sessions from this user are observing the mailbox; drops
all of the messages.

=cut

sub unload {
    my $self = shift;
    $self->is_loaded(undef);
    my @messages = @{$self->messages || []};
    $self->messages( [] );
    $self->uids( {} );
    $_->prep_for_destroy for @messages;
}

1;




More information about the Net-IMAP-Server mailing list