avo has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
I wrote a small web IMAP client using Mail::IMAPTalk. Everything works fine but I wasn't happy with the fact that I am creating new object of the class IMAP (Mail::IMAPTalk->new()) every time I am dealing with the IMAP server which is why I created a variable which stores the object and queries whether it is fine by using the is_open() method.
The reason for that is that this way I sort of created a persistent link to IMAP server which saved some latency delays which increased the speed of the program dramaticaly.
My setup for this application is simple - I have one index.cgi file which uses application.pm which contains one function main_program and set of shared variables (using "our" declarations). However looks like the variable which I use to store the IMAP object sometime looses it's value and I can't go around this. What is the way to not loose the object and have it in my application? Looks like Apache forks and not all processes has the same copy of this variable? Does that make any sense?

Herewith a sample of the setup I have:

index.cgi file:
use lib "/wwwroot/myimap/"; use myimap; &myimap::myimap;

myimap.pm file:
package myimap; our $our_cache_imap_object; sub helpdesk { if (ENTRY_POINT_FOR_CGI_ACTION...) { my $imap; if ( ! exists $our_cache_imap_object ) { # open the + imap connection using IMAP::Talk $imap = Ma +il::IMAPTalk->new( + Server => $server, + Port => $imap_port, + Username => $login, + Password => $password, + Separator => "\\", + RootFolder => '', + CaseInsensitive => 1, + Uid => 1) + || die "Connection failed. Reason: $@"; + + $our_cache_imap_object = $imap; + } elsif ($our_cach +e_imap_object->is_open()) { $imap = $our_c +ache_imap_object; } DEAL WITH THE IMAP OBJECT .... ETC. } } 1;

Replies are listed 'Best First'.
Re: Mail::IMAPTalk and mod_perl
by kirillm (Friar) on Aug 18, 2008 at 22:56 UTC

    You have:

    if ( ! exists $our_cache_imap_object ) {

    there. exists checks if a hask or array element does exist. You should rather check whether the object is defined, e.g.:

    if ( ! defined $our_cache_imap_object ) {

    Mail::IMAPTalk's constructor supports being passed a reference to a Socket. You can do some magic with that. You might want to take a look at Socket::PassAccessRights, which you could use to pass sockets to an external daemon, which would ensure that the connection is not lost and get the sockets back agian.

      Sorry, copy - paste mistake... I was just making a small example of what the real program does. The real program keeps the objects into a hash. In other words $our_cache_imap_object is actually $our_cache_imap_object{$login$userid}. When copying and pasting I never read carefully what I am publishing. The case is checking for defined actually. Do you know whether I can somehow open a shared (per module) socket upon loading of the module by Apache in mod_perl environment?
Re: Mail::IMAPTalk and mod_perl
by jethro (Monsignor) on Aug 19, 2008 at 11:51 UTC
    You could compile apache to use a different MPM module. Instead of the standard prefork (on unix) some other more thread-heavy module could decrease the number of forks dramatically. If your web server already uses a different MPM module (httpd -l shows you which one is compiled into apache), it should suffice to change some parameters in apache2.conf