Removed System.out and System.err logging. Using native java logging support

This commit is contained in:
Jonathan Leibiusky
2010-10-01 15:13:53 -03:00
parent 9db72b749c
commit 45bb728425

View File

@@ -6,20 +6,25 @@ import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* Abstract resource pool of type T. * Abstract resource pool of type T.
* <p/> *
* Needs implementation for creation, validation and destruction of the * Needs implementation for creation, validation and destruction of the
* resources. * resources.
* <p/> *
* Keeps a fixed amount of resources * Keeps a fixed amount of resources
* *
* @author Luis Dario Simonassi * @author Luis Dario Simonassi
*
* @param <T> * @param <T>
* The type of the resource to be managed. * The type of the resource to be managed.
*/ */
public abstract class FixedResourcePool<T> { public abstract class FixedResourcePool<T> {
private static Logger logger = Logger.getLogger(FixedResourcePool.class
.getName());
/* /*
* Generic Inner Control Classes ------- ----- ------- ------- * Wrapper * * Generic Inner Control Classes ------- ----- ------- ------- * Wrapper *
@@ -47,16 +52,6 @@ public abstract class FixedResourcePool<T> {
} }
} }
public abstract static class Printer {
public abstract void print(String str);
}
public static class DefaultPrinter extends Printer {
public void print(String str) {
System.out.println(str);
}
}
/** /**
* Generic Repair Thread * Generic Repair Thread
*/ */
@@ -79,6 +74,9 @@ public abstract class FixedResourcePool<T> {
continue; continue;
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe(e.getMessage());
}
continue; continue;
} }
@@ -91,14 +89,14 @@ public abstract class FixedResourcePool<T> {
if (resource != null) { if (resource != null) {
valid = isResourceValid(resource); // Validate the resource. valid = isResourceValid(resource); // Validate the resource.
if (!valid) if (!valid)
fails++; metrics.fails++;
} }
// If resource is invalid or null, create a new resource and // If resource is invalid or null, create a new resource and
// destroy the invalid one. // destroy the invalid one.
if (!valid) { if (!valid) {
T replace = createResource(); T replace = createResource();
resourcesCreated++; metrics.resourcesCreated++;
wrapper.wrapped = replace; wrapper.wrapped = replace;
if (resource != null) if (resource != null)
destroyResource(resource); destroyResource(resource);
@@ -109,14 +107,18 @@ public abstract class FixedResourcePool<T> {
// Offer the resource to the available resources pool. // Offer the resource to the available resources pool.
if (!availableQueue.offer(wrapper)) { if (!availableQueue.offer(wrapper)) {
System.err if (logger.isLoggable(Level.SEVERE)) {
.println("This shouldn't happen, offering to available was rejected."); logger
.severe("This shouldn't happen, offering to available was rejected.");
}
} }
} }
println("Ending thread [" if (logger.isLoggable(Level.INFO)) {
logger.info("Ending thread ["
+ Thread.currentThread().getName() + "]"); + Thread.currentThread().getName() + "]");
} }
}
/** /**
* Check if resources in the idle queue needs to be repaired * Check if resources in the idle queue needs to be repaired
@@ -153,13 +155,17 @@ public abstract class FixedResourcePool<T> {
if (repairNeeded) { if (repairNeeded) {
if (!repairQueue.offer(wrapper)) { if (!repairQueue.offer(wrapper)) {
System.err if (logger.isLoggable(Level.SEVERE)) {
.print("FATAL: This shouldn't happen, offering to repairing was rejected."); logger
.severe("FATAL: This shouldn't happen, offering to repairing was rejected.");
}
} }
} else { } else {
if (!availableQueue.offer(wrapper)) { if (!availableQueue.offer(wrapper)) {
System.err if (logger.isLoggable(Level.SEVERE)) {
.print("FATAL: This shouldn't happen, offering to available was rejected."); logger
.severe("FATAL: This shouldn't happen, offering to available was rejected.");
}
} }
} }
} }
@@ -169,14 +175,15 @@ public abstract class FixedResourcePool<T> {
/* /*
* Pool metrics * Pool metrics
*/ */
Metrics metrics;
public static class Metrics {
private volatile long failsReported = 0; private volatile long failsReported = 0;
private volatile long fails = 0; private volatile long fails = 0;
private volatile long resourcesCreated = 0; private volatile long resourcesCreated = 0;
private volatile long resourcesProvided = 0; private volatile long resourcesProvided = 0;
private volatile long resourcesReturned = 0; private volatile long resourcesReturned = 0;
private Printer printer = new DefaultPrinter();
/* /*
* Pool metrics accessing methods. * Pool metrics accessing methods.
*/ */
@@ -200,13 +207,14 @@ public abstract class FixedResourcePool<T> {
public long getResourcesReturned() { public long getResourcesReturned() {
return resourcesReturned; return resourcesReturned;
} }
}
/* /*
* Pool status structures * Pool status structures
*/ */
private LinkedBlockingQueue<Wrapper<T>> availableQueue; private LinkedBlockingQueue<Wrapper<T>> availableQueue;
private LinkedBlockingQueue<Wrapper<T>> repairQueue; private LinkedBlockingQueue<Wrapper<T>> repairQueue;
private final HashMap<T, Wrapper<T>> inUse = new HashMap<T, Wrapper<T>>(); private HashMap<T, Wrapper<T>> inUse = new HashMap<T, Wrapper<T>>();
private RepairThread[] repairThreads; private RepairThread[] repairThreads;
private Timer t; private Timer t;
private boolean initializated = false; private boolean initializated = false;
@@ -220,6 +228,7 @@ public abstract class FixedResourcePool<T> {
private int resourcesNumber = 10; private int resourcesNumber = 10;
private int repairThreadsNumber = 3; private int repairThreadsNumber = 3;
private long timeBetweenValidation = 150000; private long timeBetweenValidation = 150000;
private long destructionWait = 10000;
/* /*
* Bean pool configuration * Bean pool configuration
@@ -252,6 +261,14 @@ public abstract class FixedResourcePool<T> {
this.timeBetweenValidation = timeBetweenValidation; this.timeBetweenValidation = timeBetweenValidation;
} }
public long getDestructionWait() {
return destructionWait;
}
public void setDestructionWait(long destructionWait) {
this.destructionWait = destructionWait;
}
public void setName(String name) { public void setName(String name) {
if (initializated) if (initializated)
throw new IllegalStateException( throw new IllegalStateException(
@@ -260,9 +277,8 @@ public abstract class FixedResourcePool<T> {
} }
public String getName() { public String getName() {
if (name == null || name.isEmpty()) { if (name == null)
name = this.getClass().getName(); name = getClass().getName();
}
return name; return name;
} }
@@ -274,27 +290,98 @@ public abstract class FixedResourcePool<T> {
return defaultPoolWait; return defaultPoolWait;
} }
public void setPrinter(Printer printer) { /**
this.printer = printer; * Pool initialization & destruction
*/
/**
* Initialize the pool
*/
@SuppressWarnings("unchecked")
public void init() {
if (initializated == true) {
if (logger.isLoggable(Level.WARNING)) {
logger.severe("Warning, double initialization of [" + this
+ "]");
}
return;
} }
private void println(String str) { initializated = true;
if(printer != null) metrics = new Metrics();
printer.print(str);
// Create queues with maximum possible capacity
availableQueue = new LinkedBlockingQueue<Wrapper<T>>(resourcesNumber);
repairQueue = new LinkedBlockingQueue<Wrapper<T>>(resourcesNumber);
// Create and start the repair threads.
repairThreads = new FixedResourcePool.RepairThread[repairThreadsNumber];
for (int i = 0; i < repairThreads.length; i++) {
repairThreads[i] = new RepairThread();
repairThreads[i].setName("REPAIR[" + i + "]:" + name);
repairThreads[i].start();
}
// Create resource wrappers with null content.
for (int i = 0; i < resourcesNumber; i++) {
if (!repairQueue.offer(new Wrapper<T>(null)))
throw new IllegalStateException(
"What!? not enough space in the repairQueue to offer the element. This shouldn't happen!");
}
// Schedule a status report every 10 seconds.
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
if (logger.isLoggable(Level.FINE)) {
StringBuilder sb = new StringBuilder();
sb.append("**********************************");
sb.append("* Pool name:[" + name + "]");
sb.append("* resourcesCreated....:"
+ metrics.getResourcesCreated());
sb.append("* failsReported.......:"
+ metrics.getFailsReported());
sb.append("* fails...............:" + metrics.getFails());
sb.append("* resourcesCreated....:"
+ metrics.getResourcesCreated());
sb.append("* resourcesProvided...:"
+ metrics.getResourcesProvided());
sb.append("* resourcesReturned...:"
+ metrics.getResourcesReturned());
sb
.append("* available size......:"
+ availableQueue.size());
sb.append("* repair size.........:" + repairQueue.size());
sb.append("**********************************");
logger.fine(sb.toString());
}
}
}, 10000, 10000);
if (logger.isLoggable(Level.INFO)) {
logger.info("Initialized [" + name + "]");
}
} }
/** /**
* Pool initialization & destruction * Destroy the pool. After being destroyed the pool can be initialized
* again.
*/ */
public void destroy() { public void destroy() {
checkInit(); checkInit();
println("Destroying [" + getName() + "]..."); if (logger.isLoggable(Level.INFO)) {
logger.info("Destroying [" + getName() + "]...");
}
// Signal al threads to end // Signal al threads to end
finishing = true; finishing = true;
println("Destroying [" + getName() + "] threads"); if (logger.isLoggable(Level.INFO)) {
logger.info("Destroying [" + getName() + "] threads");
}
// Wait for the Repair Threas // Wait for the Repair Threas
for (int i = 0; i < repairThreads.length; i++) { for (int i = 0; i < repairThreads.length; i++) {
boolean joined = false; boolean joined = false;
@@ -304,27 +391,44 @@ public abstract class FixedResourcePool<T> {
repairThreads[i].join(); repairThreads[i].join();
joined = true; joined = true;
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); if (logger.isLoggable(Level.SEVERE)) {
logger.severe(e.getMessage());
}
} }
} while (!joined); } while (!joined);
} }
println("Waiting for [" + getName() if (logger.isLoggable(Level.INFO)) {
+ "] resources to be returned."); logger.info("Waiting at most [" + getDestructionWait()
+ "]ms for [" + getName() + "] resources to be returned.");
}
// Wait for all resources to be returned to the pool // Wait for all resources to be returned to the pool
long t1 = System.currentTimeMillis();
synchronized (this) { synchronized (this) {
while (!inUse.isEmpty()) { while (!inUse.isEmpty()) {
try { try {
this.wait(); this.wait(getDestructionWait());
long t2 = System.currentTimeMillis();
if ((t2 - t1 > getDestructionWait()) & !inUse.isEmpty()) {
if (logger.isLoggable(Level.INFO)) {
logger
.info("Resource wait timeout. Forcing inUse resources destruction.");
}
for (T used : inUse.keySet()) {
destroyResource(used);
}
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); if (logger.isLoggable(Level.SEVERE)) {
logger.severe(e.getMessage());
}
} }
} }
} }
printStatistics(); if (logger.isLoggable(Level.INFO)) {
logger.info("Destroying [" + getName() + "] resources.");
println("Destroying [" + getName() + "] resources."); }
// Destroy resources // Destroy resources
for (Wrapper<T> resource : availableQueue) { for (Wrapper<T> resource : availableQueue) {
destroyResource(resource.wrapped); destroyResource(resource.wrapped);
@@ -341,81 +445,22 @@ public abstract class FixedResourcePool<T> {
repairQueue = null; repairQueue = null;
// Destroy metrics timer // Destroy metrics timer
println("Shuting metrics timer for [" + getName() if (logger.isLoggable(Level.INFO)) {
+ "] down."); logger.info("Shuting metrics timer for [" + getName() + "] down.");
}
t.cancel(); t.cancel();
t = null; t = null;
// Reset metrics // Reset metrics
failsReported = 0; metrics = null;
fails = 0;
resourcesCreated = 0;
resourcesProvided = 0;
resourcesReturned = 0;
// Set states to initial values // Set states to initial values
initializated = false; initializated = false;
finishing = false; finishing = false;
println("Pool [" + getName() + "] successfully destroyed."); if (logger.isLoggable(Level.INFO)) {
logger.info("Pool [" + getName() + "] successfully destroyed.");
} }
/**
* Initialize the pool
*/
@SuppressWarnings("unchecked")
public void init() {
if (initializated == true) {
println("Warning, double initialization of [" + this
+ "]");
return;
}
initializated = true;
// Create queues with maximum possible capacity
availableQueue = new LinkedBlockingQueue<Wrapper<T>>(resourcesNumber);
repairQueue = new LinkedBlockingQueue<Wrapper<T>>(resourcesNumber);
// Create and start the repair threads.
repairThreads = new FixedResourcePool.RepairThread[repairThreadsNumber];
for (int i = 0; i < repairThreads.length; i++) {
repairThreads[i] = new RepairThread();
repairThreads[i].setName("REPAIR[" + i + "]:" + getName());
repairThreads[i].start();
}
// Create resource wrappers with null content.
for (int i = 0; i < resourcesNumber; i++) {
if (!repairQueue.offer(new Wrapper<T>(null)))
throw new IllegalStateException(
"What!? not enough space in the repairQueue to offer the element. This shouldn't happen!");
}
// Schedule a status report every 10 seconds.
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
printStatistics();
}
}, 10000, 10000);
println("Initialized [" + name + "]");
}
private void printStatistics() {
println("**********************************" +
"\n* Pool name:[" + name + "]" +
"\n* resourcesCreated....:" + getResourcesCreated() +
"\n* failsReported.......:" + getFailsReported() +
"\n* fails...............:" + getFails() +
"\n* resourcesCreated....:" + getResourcesCreated() +
"\n* resourcesProvided...:" + getResourcesProvided() +
"\n* resourcesReturned...:" + getResourcesReturned() +
"\n* available size......:" + availableQueue.size() +
"\n* repair size.........:" + repairQueue.size() +
"\n**********************************");
} }
protected void checkInit() { protected void checkInit() {
@@ -471,7 +516,7 @@ public abstract class FixedResourcePool<T> {
throw new IllegalStateException( throw new IllegalStateException(
"This shouldn't happen. Offering to available queue rejected."); "This shouldn't happen. Offering to available queue rejected.");
} }
resourcesReturned++; metrics.resourcesReturned++;
if (finishing) { if (finishing) {
synchronized (this) { synchronized (this) {
@@ -503,7 +548,7 @@ public abstract class FixedResourcePool<T> {
if (!repairQueue.offer(wrapper)) if (!repairQueue.offer(wrapper))
throw new IllegalStateException( throw new IllegalStateException(
"This shouldn't happen. Offering to repair queue rejected."); "This shouldn't happen. Offering to repair queue rejected.");
resourcesReturned++; metrics.resourcesReturned++;
if (finishing) { if (finishing) {
synchronized (this) { synchronized (this) {
@@ -526,7 +571,8 @@ public abstract class FixedResourcePool<T> {
/** /**
* Get a resource from the pool. * Get a resource from the pool.
* *
* @param maxTime Max time you would like to wait for the resource * @param maxTime
* Max time you would like to wait for the resource
* @return * @return
* @throws TimeoutException * @throws TimeoutException
*/ */
@@ -550,11 +596,13 @@ public abstract class FixedResourcePool<T> {
synchronized (inUse) { synchronized (inUse) {
inUse.put(ret.wrapped, ret); inUse.put(ret.wrapped, ret);
} }
resourcesProvided++; metrics.resourcesProvided++;
return ret.wrapped; return ret.wrapped;
} }
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
e1.printStackTrace(); if (logger.isLoggable(Level.SEVERE)) {
logger.severe(e1.getMessage());
}
} // If the wait gets interrupted, doesn't matter but print it (just } // If the wait gets interrupted, doesn't matter but print it (just
// in case). // in case).
} while (true); } while (true);
@@ -565,7 +613,9 @@ public abstract class FixedResourcePool<T> {
*/ */
/** /**
* Create a resource for the pool * Create a resource for the pool. This method is always called from the
* REPAIR threads. If it's impossible to create the resource, this method
* should wait or hold until resource creation becomes possible.
*/ */
protected abstract T createResource(); protected abstract T createResource();