
com.sampullara.util.FutureWriter Maven / Gradle / Ivy
package com.sampullara.util;
import com.sampullara.mustache.Mustache;
import com.sampullara.mustache.MustacheTrace;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* This class sit in front of a writer and doesn't flush until Done is called on it. Until then it queues up
* writes that may not even be completed yet. They are flushed out in the order they are enqueued.
*
* User: sam
* Date: May 6, 2010
* Time: 2:44:42 PM
*/
public class FutureWriter extends Writer {
private AppendableCallable last;
private ConcurrentLinkedQueue> ordered = new ConcurrentLinkedQueue>();
private static ExecutorService es;
static {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue(10), new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadFactory(new ThreadFactory() {
int i = 0;
@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
thread.setName("Mustache-FutureWriter-" + i++);
return thread;
}
});
es = executor;
}
private Writer writer;
private boolean closed = false;
public static void setExecutorService(ExecutorService es) {
ExecutorService old = FutureWriter.es;
// Switch to the new one
FutureWriter.es = es;
// Gracefully shutdown the old one
old.shutdown();
}
public static ExecutorService getExecutorService() {
return es;
}
public FutureWriter() {
}
public FutureWriter(Writer writer) {
this.writer = writer;
}
public Writer getWriter() {
return writer;
}
public void setWriter(Writer writer) {
this.writer = writer;
}
public static void shutdown() {
if (es != null) {
es.shutdownNow();
}
}
/**
* Optimize for the degenerate case of a set of strings being appended to the writer.
*
* @param cs
* @throws IOException
*/
public void enqueue(CharSequence cs) throws IOException {
if (closed) {
throw new IOException("closed");
}
if (last != null) {
last.append(cs);
} else {
AppendableCallable call = new AppendableCallable(cs);
enqueue(call);
last = call;
}
}
public void enqueue(Callable
© 2015 - 2025 Weber Informatics LLC | Privacy Policy