POP: load big messages in a separate thread

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2118 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2013-05-14 20:35:29 +00:00
parent 1605400e1e
commit b55a273921
3 changed files with 82 additions and 49 deletions

View File

@ -0,0 +1,73 @@
package davmail.exchange;
import org.apache.log4j.Logger;
import javax.mail.MessagingException;
import java.io.IOException;
import java.io.OutputStream;
/**
* Message load thread.
* Used to avoid timeouts over POP and IMAP
*/
public class MessageLoadThread extends Thread {
private static final Logger LOGGER = Logger.getLogger(MessageLoadThread.class);
protected boolean isComplete = false;
protected ExchangeSession.Message message;
protected IOException ioException;
protected MessagingException messagingException;
protected MessageLoadThread(String threadName, ExchangeSession.Message message) {
super(threadName + "-LoadMessage");
setDaemon(true);
this.message = message;
}
public void run() {
try {
message.loadMimeMessage();
} catch (IOException e) {
ioException = e;
} catch (MessagingException e) {
messagingException = e;
} finally {
isComplete = true;
}
}
/**
* Load mime message in a separate thread if over 1MB.
* Send a space character every ten seconds to avoid client timeouts
*
* @param message message
* @param outputStream output stream
* @throws IOException on error
* @throws MessagingException on error
*/
public static void loadMimeMessage(ExchangeSession.Message message, OutputStream outputStream) throws IOException, MessagingException {
if (message.size < 1024 * 1024) {
message.loadMimeMessage();
} else {
LOGGER.debug("Load large message " + (message.size / 1024) + "KB uid " + message.getUid() + " imapUid " + message.getImapUid() + " in a separate thread");
try {
MessageLoadThread messageLoadThread = new MessageLoadThread(currentThread().getName(), message);
messageLoadThread.start();
while (!messageLoadThread.isComplete) {
messageLoadThread.join(10000);
LOGGER.debug("Still loading uid " + message.getUid() + " imapUid " + message.getImapUid());
outputStream.write(' ');
outputStream.flush();
}
if (messageLoadThread.ioException != null) {
throw messageLoadThread.ioException;
}
if (messageLoadThread.messagingException != null) {
throw messageLoadThread.messagingException;
}
} catch (InterruptedException e) {
throw new IOException(e + " " + e.getMessage());
}
}
}
}

View File

@ -30,6 +30,7 @@ import davmail.exception.HttpNotFoundException;
import davmail.exception.InsufficientStorageException;
import davmail.exchange.ExchangeSession;
import davmail.exchange.ExchangeSessionFactory;
import davmail.exchange.MessageLoadThread;
import davmail.ui.tray.DavGatewayTray;
import davmail.util.IOUtil;
import davmail.util.StringUtil;
@ -755,31 +756,6 @@ public class ImapConnection extends AbstractConnection {
sendClient("* " + currentFolder.recent + " RECENT");
}
class MessageLoadThread extends Thread {
boolean isComplete = false;
ExchangeSession.Message message;
IOException ioException;
MessagingException messagingException;
MessageLoadThread(String threadName, ExchangeSession.Message message) {
super(threadName + "-LoadMessage");
setDaemon(true);
this.message = message;
}
public void run() {
try {
message.loadMimeMessage();
} catch (IOException e) {
ioException = e;
} catch (MessagingException e) {
messagingException = e;
} finally {
isComplete = true;
}
}
}
class MessageWrapper {
protected OutputStream os;
protected StringBuilder buffer;
@ -808,30 +784,7 @@ public class ImapConnection extends AbstractConnection {
// flush current buffer
os.write(buffer.toString().getBytes());
buffer.setLength(0);
if (message.size < 1024 * 1024) {
message.loadMimeMessage();
} else {
LOGGER.debug("Load large message " +(message.size / 1024)+"KB uid "+ message.imapUid + " in a separate thread");
try {
MessageLoadThread messageLoadThread = new MessageLoadThread(currentThread().getName(), message);
messageLoadThread.start();
while (!messageLoadThread.isComplete) {
messageLoadThread.join(10000);
LOGGER.debug("Still loading " + message.imapUid);
os.write(' ');
os.flush();
}
if (messageLoadThread.ioException != null) {
throw messageLoadThread.ioException;
}
if (messageLoadThread.messagingException != null) {
throw messageLoadThread.messagingException;
}
} catch (InterruptedException e) {
throw new IOException(e + " " + e.getMessage());
}
}
MessageLoadThread.loadMimeMessage(message, os);
}
}

View File

@ -25,6 +25,7 @@ import davmail.Settings;
import davmail.exchange.DoubleDotOutputStream;
import davmail.exchange.ExchangeSession;
import davmail.exchange.ExchangeSessionFactory;
import davmail.exchange.MessageLoadThread;
import davmail.ui.tray.DavGatewayTray;
import davmail.util.IOUtil;
import org.apache.log4j.Logger;
@ -204,6 +205,12 @@ public class PopConnection extends AbstractConnection {
sendOK("");
DoubleDotOutputStream doubleDotOutputStream = new DoubleDotOutputStream(os);
ExchangeSession.Message message = messages.get(messageNumber);
// load big messages in a separate thread
os.write("+OK ".getBytes());
MessageLoadThread.loadMimeMessage(message, os);
sendClient("");
IOUtil.write(message.getRawInputStream(), doubleDotOutputStream);
doubleDotOutputStream.close();
if (Settings.getBooleanProperty("davmail.popMarkReadOnRetr")) {