----- Original Message ----- From: "Stefano Bagnara" <[EMAIL PROTECTED]>
To: "James Developers List" <[email protected]>
Cc: "Ofir Gross" <[EMAIL PROTECTED]>
Sent: Sunday, January 22, 2006 4:18 PM
Subject: Memory, Large messages and SharedInputStreams (Was: Apache James /
JAMES-134)



When the SMTPServer receive a new message it currently create a new
MailImpl using the "public MailImpl(String name, MailAddress sender,
Collection recipients, InputStream messageIn)" costructor.
That constructor create a new MimeMessageSource using the InputStream from
the socket (new MimeMessageInputStreamSource(name, messageIn);)
MimeMessageInputStreamSource currently store the message in a .m64 file
and eventually provide the stream to the following users:

public synchronized InputStream getInputStream() throws IOException {
   return new BufferedInputStream(new FileInputStream(file));
}

This is the first step.
Maybe we should start changing the MimeMessageInputStreamSource to provide
a Shared input stream?!?

Then, when a message is stored in a dbfile repository then the header is
stored in the body field of the repository db table while the body of the
message is stored in a streamrepository.

This is exactly what I do at the moment.
MimeMessageInputStreamSource.getInputStream() returns a
SharedFileInputStream reading from the .m64 file.

What I also do is using the dbfile repository by default, storing the body
in the file-rep if the size is above 5 MB or else together with the header
in the db.

Storing the body in the file-rep is a simple file-move-operation. The
problem with the SharedFileInputStream is, that as soon you create it one
can not move the file anymore, because of the open stream. So everytime I
move the .m64 into the file-rep I have to close the SharedInputStream and
reopen it afterwards.

This way the changes affect MimeMessageInputStreamSource and
MimeMessageWrapper (as far I can remember). This works in my version of JAMES but not in the official 2.1.3 (tested 6 month ago) mine is based on. There are other places in 2.1.3 where
the Message is loaded into memory, but I didn't any further investigation.

Before trying this I eliminated each call to
MimeMessageWrapper.loadMessage() when I rewrote JAMES in 2002.

The only time the message needs to be loaded  is when its content is
changed. Though the javamail docu states that saveChanges() should be
called after a MimeMessage has been changed, doing so only results in
loading the Message into memory (without SharedInputStream) in order to ensure the right encoding. But
if you know what encoding to apply to your changes (probably none)
there's no need to call it.

But using SharedInputStream is the way to go.

Markus
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to