/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
*/
/**
* A Text Writer which writes log records asynchronously to
* character-based stream. Note that this implementation is
* parallel unbound ie there is no queue size cap imposed.
*/
public class ParallelTextWriter
implements ServerShutdownListener, TextWriter
{
/**
* The wrapped Text Writer.
*/
/** Queue to store unpublished records. */
private boolean autoFlush;
/**
* Construct a new ParallelTextWriter wrapper.
*
* @param name the name of the thread.
* @param autoFlush indicates if the underlying writer should be flushed
* after the queue is flushed.
* @param writer a character stream used for output.
*/
{
this.writerThread = null;
this.stopRequested = new AtomicBoolean(false);
writerThread = new WriterThread();
}
/**
* The publisher thread is responsible for emptying the queue of log records
* waiting to published.
*/
{
public WriterThread()
{
super(name);
}
/**
* the run method of the writerThread. Run until queue is empty
* AND we've been asked to terminate
*/
public void run()
{
while (!stopRequested.get())
{
try
{
{
{
{
}
else
{
break;
}
}
if (autoFlush)
{
flush();
}
}
}
catch (InterruptedException ex)
{
// Ignore. We'll rerun the loop
// and presumably fall out.
}
}
}
}
/**
* Write the log record asyncronously.
*
* @param record the log record to write.
*/
{
// No writer? Off to the bit bucket.
while (!stopRequested.get())
{
// Put request on queue for writer
break;
}
}
}
/**
* {@inheritDoc}
*/
public void flush()
{
}
/**
* {@inheritDoc}
*/
public long getBytesWritten()
{
return writer.getBytesWritten();
}
/**
* Retrieves the wrapped writer.
*
* @return The wrapped writer used by this asyncronous writer.
*/
{
return writer;
}
/**
* {@inheritDoc}
*/
{
return "ParallelTextWriter Thread " + name;
}
/**
* {@inheritDoc}
*/
{
// Don't shutdown the wrapped writer on server shutdown as it
// might get more write requests before the log publishers are
// manually shutdown just before the server process exists.
shutdown(false);
}
/**
* {@inheritDoc}
*/
public void shutdown()
{
shutdown(true);
}
/**
* Releases any resources held by the writer.
*
* @param shutdownWrapped If the wrapped writer should be closed as well.
*/
{
stopRequested.set(true);
// Wait for publisher thread to terminate
try {
// Interrupt the thread if its blocking
writerThread.join();
}
catch (InterruptedException ex) {
// Ignore; we gotta wait..
}
}
// The writer writerThread SHOULD have drained the queue.
// If not, handle outstanding requests ourselves,
// and push them to the writer.
}
// Shutdown the wrapped writer.
}
/**
* Set the auto flush setting for this writer.
*
* @param autoFlush If the writer should flush the buffer after every line.
*/
{
}
}