package org.csc.phynixx.loggersystem.logrecord;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.csc.phynixx.common.exceptions.DelegatedRuntimeException;
import org.csc.phynixx.common.generator.IDGenerator;
import org.csc.phynixx.common.generator.IDGenerators;
import org.csc.phynixx.common.logger.IPhynixxLogger;
import org.csc.phynixx.common.logger.PhynixxLogManager;
import org.csc.phynixx.loggersystem.logger.IDataLogger;
import org.csc.phynixx.loggersystem.logger.IDataLoggerFactory;
/**
* This provider doesn't reuse released and reset IXADataLogger
*
* @author te_zf4iks2
*
*/
public class XADataRecorderPool implements IXARecorderProvider, IXADataRecorderLifecycleListener {
private static final IPhynixxLogger LOG = PhynixxLogManager.getLogger(XADataRecorderPool.class);
private class XADataLoggerPooledObjectFactory extends BasePooledObjectFactory<IXADataRecorder> {
private IDataLoggerFactory dataLoggerFactory = null;
private IDGenerator<Long> messageSeqGenerator = IDGenerators.synchronizeGenerator(IDGenerators
.createLongGenerator(1l));
public XADataLoggerPooledObjectFactory(IDataLoggerFactory dataLoggerFactory) {
super();
this.dataLoggerFactory = dataLoggerFactory;
if (this.dataLoggerFactory == null) {
throw new IllegalArgumentException("No dataLoggerFactory set");
}
}
public String getLoggerSystemName() {
return dataLoggerFactory.getLoggerSystemName();
}
void destroyResources() {
this.dataLoggerFactory.cleanup();
this.messageSeqGenerator = null;
}
/**
*
* {@link PooledObjectFactory}
*/
@Override
public IXADataRecorder create() throws Exception {
return this.createXADataRecorder();
}
@Override
public PooledObject<IXADataRecorder> wrap(IXADataRecorder obj) {
return new DefaultPooledObject<>(obj);
}
@Override
public void destroyObject(PooledObject<IXADataRecorder> p) throws Exception {
// TODO Auto-generated method stub
super.destroyObject(p);
}
@Override
public boolean validateObject(PooledObject<IXADataRecorder> p) {
// TODO Auto-generated method stub
return super.validateObject(p);
}
/**
* opens a new Recorder for writing. The recorder gets a new ID.
*
* The lifecycle of the dataRecorder is managed by the current implementation of {@link
*
* @return created dataRecorder
*/
private IXADataRecorder createXADataRecorder() {
try {
long xaDataRecorderId = this.messageSeqGenerator.generate();
// create a new Logger
IDataLogger dataLogger = this.dataLoggerFactory.instanciateLogger(Long.toString(xaDataRecorderId));
// create a new XADataLogger
XADataLogger xaDataLogger = new XADataLogger(dataLogger);
PhynixxXADataRecorder xaDataRecorder = PhynixxXADataRecorder.openRecorderForWrite(xaDataRecorderId,
xaDataLogger, XADataRecorderPool.this);
LOG.info("IXADataRecord " + xaDataRecorderId + " created in [" + Thread.currentThread() + "]");
return xaDataRecorder;
} catch (Exception e) {
throw new DelegatedRuntimeException(e);
}
}
}
private final XADataLoggerPooledObjectFactory dataLoggerPooledObjectFactory;
private final GenericObjectPool<IXADataRecorder> objectPool;
public XADataRecorderPool(IDataLoggerFactory dataLoggerFactory) {
this.dataLoggerPooledObjectFactory = new XADataLoggerPooledObjectFactory(dataLoggerFactory);
GenericObjectPoolConfig cfg = new GenericObjectPoolConfig();
cfg.setTestOnBorrow(true);
cfg.setTestOnReturn(true);
cfg.setMaxTotal(Integer.MAX_VALUE);
this.objectPool = new GenericObjectPool<>(this.dataLoggerPooledObjectFactory, cfg);
}
@Override
public boolean isClosed() {
return this.objectPool.isClosed();
}
@Override
public IXADataRecorder provideXADataRecorder() {
try {
return this.objectPool.borrowObject();
} catch (Exception e) {
throw new DelegatedRuntimeException(e);
}
}
@Override
public void close() {
if (this.isClosed()) {
return;
}
this.objectPool.close();
}
@Override
public void destroy() {
try {
this.close();
} catch (Exception e) {
}
this.dataLoggerPooledObjectFactory.destroyResources();
}
/**
*
* {@link IXADataRecorderLifecycleListener}
*/
@Override
public void recorderDataRecorderClosed(IXADataRecorder xaDataRecorder) {
try {
this.objectPool.invalidateObject(xaDataRecorder);
} catch (Exception e) {
throw new DelegatedRuntimeException(e);
}
}
@Override
public void recorderDataRecorderOpened(IXADataRecorder xaDataRecorder) {
// dataRecorder is created by the pool; no further notification
// neccessary
}
@Override
public void recorderDataRecorderReleased(IXADataRecorder xaDataRecorder) {
this.objectPool.returnObject(xaDataRecorder);
}
}