Skip to content

Instantly share code, notes, and snippets.

@jeffsheets
Last active June 15, 2016 16:29
Embed
What would you like to do?
Grails setup for using Apache Commons Pool to pool JAX-WS Port Proxy WS Stub objects because creating the connections can be an expensive operation
import org.apache.commons.pool2.ObjectPool
import org.apache.log4j.Logger
class PoolHelper {
static Logger log = Logger.getLogger(PoolHelper)
/**
* Executes a closure using the object from the passed
* in Commons Pool, invalidating the object if an error is returned,
* and always returning it to the pool. Similar to how Groovy Sql methods work.
*/
static def withCommonsPool(ObjectPool pool, Closure closure) {
def borrowedObject = pool.borrowObject()
try {
return closure.call(borrowedObject)
} catch (Exception e) {
log.warn "exception caught using pool, invalidating connection", e
pool.invalidateObject(borrowedObject)
borrowedObject = null
throw e
} finally {
if (null != borrowedObject) {
pool.returnObject(borrowedObject)
}
}
}
}
dependencies {
compile "org.apache.commons:commons-pool2:2.2"
}
import static com.sheetsj.pool.PoolHelper.withCommonsPool
class GridService {
/**
* Improve JAX-WS performance by reusing connections.
* Pool defined in resources.groovy
*/
ObjectPool ruleConnectionPool
/**
* Gets rules using a free connection from the connection pool
*/
def getGridRules(String gridName) {
withCommonsPool(ruleConnectionPool) { ruleWSConn ->
def request = new RequestWSDTO(gridName: gridName)
ResponseWSDTO result = ruleWSConn.getGridMetaData(request)
result.getGridMetaDataWSDTO()
}
}
}
import java.util.UUID;
import groovy.util.Proxy
/**
* Needed so each item in pool is unique via equals method,
* but Jaxws Port calls use a Proxy that does not behave well for the equals method
* @see http://stackoverflow.com/questions/22824889/apache-pool-cant-return-object-in-spring-controller-service
*/
class JaxwsPortProxy<T> extends Proxy {
private final UUID poolId = UUID.randomUUID()
@Override
boolean equals(Object o) {
if (this == o)
return true
if (!(o instanceof JaxwsPortProxy))
return false
JaxwsPortProxy that = (JaxwsPortProxy) o
poolId == that.poolId
}
@Override
int hashCode() {
poolId?.hashCode() ?: 0
}
}
import org.apache.commons.pool2.impl.GenericObjectPool
import com.sheetsj.pool.RuleServiceFactory
beans = {
ruleServiceFactory(RuleServiceFactory)
ruleConnectionPool(GenericObjectPool, ruleServiceFactory) {
maxTotal = 10
maxIdle = 10
//61 seconds to wait for object creation
maxWaitMillis = 61000
//10 minutes before an object is evicted for being idle
minEvictableIdleTimeMillis = 10 * 60 * 1000
//2 minutes between checks for evictions
timeBetweenEvictionRunsMillis = 2 * 60 * 1000
blockWhenExhausted = true
}
}
import org.apache.commons.pool2.BasePooledObjectFactory
import org.apache.commons.pool2.PooledObject
import org.apache.commons.pool2.impl.DefaultPooledObject
class RuleServiceFactory extends BasePooledObjectFactory<JaxwsPortProxy<RuleServiceWS>> {
@Override
public JaxwsPortProxy<RuleServiceWS> create() throws Exception {
// Used to get JAX-WS Port Proxy WS Stub object
def ruleService = RuleServiceClientFactory.getRuleService()
return new JaxwsPortProxy<RuleServiceWS>().wrap(ruleService)
}
@Override
public PooledObject<JaxwsPortProxy<RuleServiceWS>> wrap(JaxwsPortProxy<RuleServiceWS> ruleService) {
return new DefaultPooledObject<JaxwsPortProxy<RuleServiceWS>>(ruleService);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment