Execute imap_close not working
Asked Answered
A

2

8

I have page with customers and with ajax im loading info on whether they send us email or not.

Code looks like this:

$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'email';
$password = 'password';

$this->session->data['imap_inbox'] = $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

 foreach($customers as $customer){
     $emails = imap_search($inbox, 'FROM ' . $email);
     // Processing info
 }

But there are roughly 20-30 customers on one page, so the proccess takes sometimes about 10-20 seconds to show and I was unable to optimize the process.

But when client tries to reload a page, it is still waiting before imap_search finishes, so when reloading it could take 20 seconds before the page is actually reloaded.

I have tried to abort the ajax with beforeunload function and close the imap but this is not working.

My code:

Ajax:

    $(window).bind('beforeunload',function(){
    imap_email.abort(); // the ajax is succesfully aborted(as showed in console), yet the page still takes considerable time to reload

    $.ajax({
        type: 'GET',
        url: 'getimapmails&kill=1',
        async:false
    }); // ajax call to the same function to call imap_close 

});

PHP:

if($this->request->get['kill'] == '1'){
            imap_close($this->session->data['imap_inbox']);
            unset($this->session->data['imap_inbox']);
            $kill == 1;
            exit;
        }

But even though the ajax is aborted and imap_close is called on variable holding imap_open, it still takes 10-20 seconds for page to reload, so I'm assuming the imap was not closed.

How do I close the imap so the page can reload immediately?

Anew answered 10/3, 2016 at 14:36 Comment(2)
Do you have any imap logs you can watch while you're refreshing to see if it is closing the connection or not? It generally feels like you need to work on imap tuning over code at this point.Setter
There may be an issue of session lock;Slam
M
2

I would recommend killing it by creating a file that causes a break:

$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'email';
$password = 'password';

$this->session->data['imap_inbox'] = $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());

 foreach($customers as $customer){
      clearstatcache(); //Can't use the cached result.
     if(file_exists('/tmp/kill_imap.'.$this->session->id)) break;  //making the assumption that /tmp and session->id are set, but the idea is a temporary folder and a unique identifier to that session.
     $emails = imap_search($inbox, 'FROM ' . $email);
     // Processing info
 }
 if(file_exists('/tmp/kill_imap.'.$this->session->id)) unlink('/tmp/kill_imap.'.$this->session->id);

Then on your exit ajax, just call to a php script that simply creates that file. and it will break your loop and remove the file.

Medarda answered 17/3, 2016 at 21:25 Comment(0)
B
1

If I understood correctly, the time-consuming code lies within the foreach() loop.

Now, even if you make a second request to kill the IMAP session, that foreach() loop will continue until either it finishes or PHP kills it if (and when) execution time exceeds your max_execution_time setting.

In any case, you need something within your foreach() loop that will check on each round if a condition to abort has been met, so as to switfly terminate the current request and allow the client to make new one.

I suggest you look at the PHP function connection_aborted(), that you could use to detect once the client aborts the current request, and more generally you could read on the topic of connection handling to get a better sense of how connections and requests are handled in PHP.

Bender answered 15/3, 2016 at 13:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.