Noel J. Bergman wrote:
I though that I should have tried to drop the "wrapping/delegation"
behaviour in favor of a simple extension.

I recall thinking the same.  And moving to a shared inputstream and
streaming should be a big win on footprint.  Dan also mentioned it, with
respect to Derby.

I just reread a thread (10-25 January 2006) with comments and code by Markus Kuhn and Ofir Gross and maybe we should also incorporate some of their suggestions. E.g: we could provide more constructors to MimeMessageWrapper so that we can use it instead of MimeMessage when "cloning" other MimeMessages.

Then we could simply fallback to a temporary sharedfile for the contentStream as like as we do while receiving smtp messages with MimeMessageInputStreamSource (that I already converted to provide sharedinputstreams, in my test).

This way it was simpler to define when the message is needed and I've
been able to avoid the message loading for most header operations
(previously needed).

This is a large part of what the wrapper was originally written to do, IIRC.
Way before I started with JAMES.

Yes, but previously the full message (instead of headers) was loaded for each setHeader operation. Now also set operations on headers try to avoid the message loading.

I made [streaming] optional by adding a new "getBody" option
(useBinaryStream) to the dbOptions in sqlResources so that
testers could try this feature over different dbs and provide
feedback.

If you can complete the changes, I'd be in favor of getting them into the
next milestone.

I've done more tests with db repositories (not dbfile) over mysql, derby and oracle and big messages (100MB+) and limited Xmx (40MB for mysql and derby, 50MB for oracle and hsqldb) and I found something:

I need to use a PipedInputStream/PipedOutputstreams with an additional buffering thread in order to store the message using streams for both mysql and derby. I tested another option (setBinaryStream on a blob obtained with "select for update") where this was not needed but both db throws various "not implemented" exceptions.

IMHO this is not a showstopper because Activation framework (JAF) already spawn similar threads when working with mimemessages. The main problem is that the exception handling is much more difficult with this kind of "worker" threads around. On the performance side we probably want to run the thread when the message is larger of, as an example, 10KB. With smaller messages we can use a bytearray buffer and avoid the additional thread (I prefer to add this easy optimization after we tested to correctness of the streaming methods).

On the mysql side the streaming operations works correctly only using mysql 4.1+, connector/j 5+ (latest connector/j 3.1.12 still have bugs) and adding an "emulateLocators=true" parameter in the jdbc url. The bad news is that using the streaming methods with older connectors/servers ends in corrupted/truncated data!

Testing hsqldb I get OutOfMemoryExceptions and Corrupted Data all the times so I skipped it.

The great news is that the same identical queries works with Oracle too! I still can't fully believe this thing (I work often with jdbc/oracle and I always had to write specific code). I only tested oracle 9.2.0.4 accessed by the latest 10G thin jdbc driver (10.1.0.4.0) (older drivers didn't work).

I changed the MimeMessageJDBCSource to provide a SharedInputStream from the db, but I'm not sure this is a good idea: currently if a message created from that source is parsed javamail open a log of new shared streams (creates new connection/queries to db). Maybe I should try to intercept the parsing and copy the stream to a temporary shared file instead of opening new connections (not totally sure it would be better)

Now I need a few (many?!) hours to put order on what I wrote and I hope I'll commit something soon. After the commit and a few more tests we'll vote on what to do with defaults. We probably should defaults to binarystreams for derby, as we exactly know what version of derby is used, and use standard bytearray operations for oracle and mysql and perhaps add a note in the config.xml explaining how to enable stream operations and what driver version/server version is needed.

As a side note I've seen that other players (activemq and jboss mail server) are using another approach to save big messages: they split the message over multiple records. I personally don't like this solution and I prefer a big restriction on the usable jdbc drivers but a full streaming support or as a last resort the file (or dbfile) repository.

Stefano

PS: I would like to alter the SMTPServer to directly stream incoming messages to DB, but unfortunately I found out that we have to know the exact size of the message before being able to stream it to db!


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

Reply via email to