package rocks.inspectit.shared.cs.storage.nio.write;
import java.nio.channels.CompletionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rocks.inspectit.shared.cs.storage.nio.WriteReadAttachment;
import rocks.inspectit.shared.cs.storage.nio.WriteReadCompletionRunnable;
/**
* Completion handler for asynchronous writing.
*
* @author Ivan Senic
*
*/
public class WritingCompletionHandler implements CompletionHandler<Integer, WriteReadAttachment> {
/**
* The log of this class. Can not be assigned via spring because this is not a component.
*/
private static final Logger LOG = LoggerFactory.getLogger(WritingCompletionHandler.class);
/**
* {@inheritDoc}
* <p>
* On writing completion the check if the whole content of the buffer has been written is done.
* If not, a new write with updated position and size is performed. If yes, the completion
* handler is invoke if it is not null.
*/
@Override
public void completed(Integer result, WriteReadAttachment attachment) {
long bytesToWriteMore = attachment.getSize() - result.longValue();
if (bytesToWriteMore > 0) {
long writingSize = bytesToWriteMore;
long writingPosition = attachment.getPosition() + result.longValue();
attachment.setPosition(writingPosition);
attachment.setSize(writingSize);
attachment.getFileChannel().write(attachment.getByteBuffer(), writingPosition, attachment, this);
} else {
WriteReadCompletionRunnable.RunnableFuture completionRunnableFuture = attachment.getCompletionRunnableFuture();
if (null != completionRunnableFuture) {
completionRunnableFuture.getWriteReadCompletionRunnable().markSuccess();
if (completionRunnableFuture.getWriteReadCompletionRunnable().isFinished()) {
completionRunnableFuture.run();
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void failed(Throwable exc, WriteReadAttachment attachment) {
LOG.error("Write to the disk failed.", exc);
WriteReadCompletionRunnable.RunnableFuture completionRunnableFuture = attachment.getCompletionRunnableFuture();
if (null != completionRunnableFuture) {
completionRunnableFuture.getWriteReadCompletionRunnable().markFailed();
if (completionRunnableFuture.getWriteReadCompletionRunnable().isFinished()) {
completionRunnableFuture.run();
}
}
}
}