Google
 
Web unafbapune.blogspot.com

Monday, September 18, 2006

 

Jaxb2 jakarta-commons-lang Plugin

Just contributed to the reference implementation of Jaxb2 a very simple plugin named jakarta-commons-lang plugin that would add toString(), hashCode() and equals() method to the xjc generated Pojo's using the Jakarta Commons' ToStringBuilder, HashCodeBuilder and EqualsBuilder.

More Jaxb2 plugins can be found here. Enjoy!

Wednesday, September 13, 2006

 

WriteThottleFilter in Mina

I was wondering if there is an easy way in Mina 0.8.2 to control the rate of physical network write operations to not exceed a specific number of messages.

For example, can I say for a particular socket connection session Mina should write physically no more than 3 messages per second ? Message here means the argument that get passed to ProtocolSession.write(Object).

AFAIK the ProtocolSession.write() is a logical asyn operation, and Mina therefore reserves the right to buffer it underneath. If so, controlling the rate of session.write() cannot be relied upon to control the rate of physical messages that get sent down the wire.

So I posted the question to the Mina developer forum, and here is the reply by Trustin Lee:
"You are correct, but you can make session.write() a blocking operation by inserting a filter which limits the write rate. Please implement your filter's filterWrite() to throttle the write request.

BTW this idea is nice. Could you please create a JIRA issue for us so we can resolve it someday and you can switch over to our version of write rate limiting filter? Otherwise you could contribute! ;)"

It turns out the implementation can be quite simple:
...
SocketConnector socketConnector = new SocketConnector();
socketConnector.getFilterChain()
.addLast("writeThrottleFilter",
new WriteThrottleFilter(333));
...

public class WriteThrottleFilter extends IoFilterAdapter
{
/** Delay in milli-seconds between writes. */
private final long delayMillis;

public WriteThrottleFilter(long delayMillis) {
this.delayMillis = delayMillis;
}

@Override
public synchronized void filterWrite(NextFilter nextFilter,
IoSession session, ByteBuffer buf, Object marker)
throws InterruptedException
{
nextFilter.filterWrite( session, buf, marker );
Thread.sleep(delayMillis);
}
}
Thanks to Trustin Lee, this class will be included in the Mina 1.0 release! More details here.

Sunday, September 10, 2006

 

ConcurrentLinkedBlockingQueue

I've been wondering why there is ConcurrentLinkedQueue in Java 5+, but not something like a ConcurrentLinkedBlockingQueue, which would allow the client to block on an empty queue via a "take" method, or block on an empty queue for a limited time via a "poll" method.

I attempted to construct one by combining the use of a Semaphore with a ConcurrentLinkedQueue, but apparently it is less scalable than the LinkedBlockingQueue.

As pointed out by Doug Lea:
"This IS a good thought....This way works, but reduces concurrency by using a single semaphore, so is a bit less scalable than current inkedBlockingQueue. However, there is a path to much better scalability by using the "dual-queue" approach similar to what we did for Java 6 SynchronousQueue. My initial intent was to find a way to internally use such techniques to replace the unbounded case of LinkedBlockingQueue. But this turns out not to work out too well because of all the little compatibility problems encountered -- for example, maintaining the same Serialization form. So it is more likely that we'll put out a separate ConcurrentLinkedBlockingQueue that will be preferable to LinkedBlockingQueue unless you need capacity constraints.
Stay tuned for it...
"
In stead of waiting, I decided to try a different path and proceeded to make a second attempt. This time the constructs I use included:
* an extra ConcurrentLinkedQueue for the parking threads
* volatile for marking if a thread is potentially parked or not
* LockSupport.[un]park[Nano](...)

One feature of such ConcurrentLinkedBlockingQueue is that it is unbounded, whereas even LinkedBlockingQueue has a max capacity of Integer.MAX_VALUE.

The source can be found here, whereas some performance tests can be found here. Some initial load testing looks promising, although I only tested it with a single procesor machine, and it appears the test result is very sensitive to the GC and heap memory configuration for the JVM. What I really need is some loading testing on a multi-processor environment where true concurrency is possible.
Update on 11Sep2006: Running the test harness on an AMD Opteron dual processor using JDK-1.5.0_05, the CLBQ is on average 72% faster than the LBQ. See here for more details.

Update on 19Sep2006:

More experiments seem to indicate that the CLBQ consistently outperform the LBQ for the mix of N-producer 1-consumer. When there are N-producer and M-consumer, however, it seems the reverse is true. Not exactly sure why. Probably CLBQ incurs a slightly higher overhead as compared to LBQ in the M-consumer situation.
Update on 4Apr2007:

If anyone has a powerful box (with multi-processors) and is interested in comparing the performance of ConcurrentLinkedBlockingQueue vs LinkedBlockingQueue, please download a jar from:
http://beanlib.sourceforge.net/clbq/070407/q-test.jar
and run it with either jdk5 or jdk6:
java -DnumConsumer=10 -DnumProducer=100 -DwcRatio=20 -server -XX:CompileThreshold=1500 -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+DisableExplicitGC -jar q-test.jar
Note:For instance, the above example means to run the test with 100 producers, 10 consumers, and a W/C ratio of 20. One interesting observation is that Windows XP Professional is really slow on LBQ even when there is only 1 producer and 1 consumer! Feel free to tinkle with the parameters, and let me know what you find.

The source jar of the test harness can be downloaded from:
http://beanlib.sourceforge.net/clbq/070407/q-test-sources.jar

This page is powered by Blogger. Isn't yours?