Saturday, December 12, 2009

Spring3 Features -TaskExecutor & TaskSchedulor

The Spring Framework provides abstractions for asynchronous execution and scheduling of tasks with the TaskExecutor and TaskScheduler interfaces, respectively.

http://docs.google.com/fileview?id=0B-0gqvlsl_VvNTBlMDdmZmUtYWE4Ni00YmRhLTk0ODAtYWNhYjk4OGM5YTk1&hl=en
[Download - rename from pdf to rar]
[Attached is the sample code for both –with annotations]

1. TaskExecutor

Spring's TaskExecutor interface is identical to the java.util.concurrent.Executor interface.

ConcurrentTaskExecutor : This implementation is a wrapper for a Java 5 java.util.concurrent.Executor.

ThreadPoolTaskExecutor : Spring's TaskExecutor implementation.

[org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor – Namespace: ]

Parametres : corePoolSize,maxPoolSize,queuecapacity,rejection-policy

The executor will first try to use a free thread if the number of active threads is currently less than the core size. If the core size has been reached, then the task will be added to the queue as long as its capacity has not yet been reached. Only then, if the queue's capacity has been reached, will the executor create a new thread beyond the core size. If the max size has also been reached, then the executor will reject the task.

By default, when a task is rejected, a thread pool executor will throw a TaskRejectedException. CallerRunsPolicy. Instead of throwing an exception or discarding tasks, that policy will simply force the thread that is calling the submit method to run the task itself. The idea is that such a caller will be busy while running that task and not able to submit other tasks immediately. Therefore it provides a simple way to throttle the incoming load while maintaining the limits of the thread pool and queue.

2. TaskScheduler

Spring 3.0 introduces a TaskScheduler with a variety of methods for scheduling tasks to run at some point in the future.

- can be associated with a pool size.

Taskschedulor.schedule() takes a trigger expression based on which tasks will be scheduled.

Annotation Support

Both have very easy annotation support.

@Async - This can be marked on any POJO method

@Scheduled- This annotation can be marked on any POJO method

Just add  in the xml and give respective scheduler or executor as properties.

Currently with spring 3 RC2 and Spring Dm 2.0M6 – I could not use namespace support as they were giving some issues. It could be a BUG and I have raised this issue in the forum.

http://forum.springsource.org/showthread.php?t=81676

In the attached sample code instead of using namespace I have used the entire class name.

Namespace should work with Spring 3 RC3 version.

Spring Integration+JMS(JBOSS)+OSGi

I have a POC for spring integration to be used along with JBoss and OSGi in Spring Dm server 2.0M6.

Code Sample
http://docs.google.com/fileview?id=0B-0gqvlsl_VvNzhiMzVmMzgtY2Y4Zi00YjJmLWJmNWQtMTIwMDZjNDViMmJl&hl=en
[Download this pdf - Rename file from pdf to rar and extract]


SwitchBoardBundle – Exposes connection factories as service

Exposes common thread pools as service

[Jboss ip values for connection factories are picked from property files]



Ara Bundle - Start a timertask which puts message into a login channel.

This channel is exposed as a service which is imported by PamClient Channel

Ara bundles defines its own thread pool and receives connectionFactory service from switchboard bundle.



PamClient Bundle - Listens to local events from ara bundle and remote events from Pamserver bundle

Imports login channel service from Ara bundle

Uses common thread pool defined in switchboard bundle

[Property file has values which can point each topic or queue to be hosted on a specific Jboss server]



PamServer Bundle – generates events on regular time intervals which will be put into Jms queue using jms adapters.

Also tested a use case where we could change connection factory without getting down the server

OSGi -Spring - Configuration Admin - Dynamic Property file changes

Normally we have been reading the property files ourselves or used spring property-holder feature or even cm-properties. In all these cases update to the property file are not visible.

You can now use the managed-properties under Configuration Admin and have the values updated in your bean automatically whenever you change the property file. You just drop a property file inside pickup directory and under the bean definition specify the persistent-id as follows:


// Have a property file with name myPropertyFile
<osgix:cm-properties id="config" persistent-id="myPropertyFile"/>

//declare a property place holder config with id of osgi:cm
<context:property-placeholder properties-ref="config"/>

//bean definition using teh property file
<bean id="configTest" class="com.test.ConfigTest">
<osgix:managed-properties persistent-id="myPropertyFile" update-strategy="container-managed" /> <property name="propertyValue" value="${propertyValue}"></property>
</bean>

Now first add the property file to the pick up folder and start the DM server. The setPropertyValue() setter will be called and the value will be initialized when application bundle is dropped.

[There are multiple calls to this setter because of the osgi configuration admin]

Now when the property file in changed in the pickup directory , the setter method will be called and new value will be set into the bean.

Incase you want to manage the updates yourself you can change the update-strategy and provide the update-method in the bean. In this case all the key/values are provided to the method in form of a Map.

<bean id="configTest" class="com.test.ConfigTest">
<osgix:managed-properties persistent-id="myPropertyFile"
update-strategy="bean-managed" update-method="refresh" />
<property name="propertyValue" value="${propertyValue}"></property>
</bean>

The ConfigTest class is as follows

public class ConfigTest {

private int propertyValue;

public void setPropertyValue(int propertyValue) {

System.out.println("setter called for property"+propertyValue);
this.propertyValue = propertyValue;
}


public void refresh(Map <String,String> keyVals)
{
System.out.println("referhs called with value"+keyVals);
}

}

PS:

Do not share the same persistent-id (PID) between multiple bundles or definitions, as only one of them will receive notifications. managed-properties relies on org.osgi.service.cm.ManagedService contract which mandates that each ManagedService instance must be identified with its own unique PID.

Hence the best option in a service model is to have a configuration service reading the property file and giving notifications to required bundles.

Interesting Java Data Structures

Vector & Collections.synchronizedList(new ArrayList()); are similar. They get the lock on the entire object.

So are HashTable and Collections.synchronizedMap(new HashMap());.

Though lock is taken on entire object - during operations like iterations they have to be in a synchronised block.Else parallel access by other thread will lead to a concurrent access exception.

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html

Solution to these are data structures like CopyOnWrtieArrayList(for list) ConcurrentHashMap(for map).

ConcurrentHashMap doesnt lock the entire object , instead allows parallel reads, when a write operation is on.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html


Similarly with CopyOnWriteArrayList there is no need to lock the entire object during iteration, as the iteration will happen on a copy object.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

RentrantReadWriteLock - This helps in taking a lock .So that all other access through this point will wait for the lock to be released. This lock is not resticted to a object and hence can be used in the business logic to get fine thread safety and synchronisation over business objects.This also provided read and write locks which will help in granular control for read and write operations.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReadWriteLock.html

Synchronizing method against block(object)

When a method is synchronized , the method object is blocked. No other thread can enter into any other synchronized method(non static) on this object.But other threads can enter into a non synchronized block on the same class.

When a block is synchronized - if its synchronised on a object ,two parallel thread can access two synchronized blocks at the same time., since locks are on two different objects.

Class level locks can be obtained by making static methods synchronized.

 
Free Domain Names @ .co.nr!