The scenario is the following:
A number of messages need to be written to a specified file. The messages arrive fine up to the FileMessageDispatcher but once they are written, some messages are missing from the file. Note that not the same amount of messages are lost. Some times all messages arrive fine. This problem probably occurs due to thread interference, with the output of one thread being overwritten by that of another.
Synchronizing the doDispatch() method seems to solve the problem. The code modification suggested is as seen below:
synchronized (mutex)
{
FileOutputStream fos = (FileOutputStream)connector.getOutputStream(event.getEndpoint(), message);
if (event.getMessage().getStringProperty(FileConnector.PROPERTY_FILENAME, null) == null)
{
event.getMessage().setStringProperty(FileConnector.PROPERTY_FILENAME,
message.getStringProperty(FileConnector.PROPERTY_FILENAME, ""));
}
try
{
fos.write(buf);
}
finally
{
fos.close();
}
}
The mutex is declared as follows:
private final static Object mutex = new Object();
Any thoughts on this?
In 1.4 all dispatcher actions are declared as unsynchronized for the dispatcher instance and always guaranteed to be performed by a single thread only, so only multiple concurrent requests to the same endpoint can conflict since they are done by multiple instances. The file transport is one of the modules that so far were not yet reviewed for the new transport architecture (see
MULE-1436).In the meantime check out AbstractConnector.get/setMaxDispatchersActive which was made for exactly the purpose of limiting the number of concurrent dispatchers. The "real" solution is to have a mutex (lock manager) by endpoint (directory path/file).
So as short-term fix configuring or hard-coding the file connector to return a constant 1 for getMaxDispatchersActive should have exactly the same effect as your mutex.