/*
* Copyright (C) 2012 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.errai.bus.server.io;
import static java.lang.System.nanoTime;
import org.jboss.errai.bus.server.api.MessageQueue;
import org.jboss.errai.bus.server.io.buffers.BufferFilter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;
/**
* @author Mike Brock
*/
public final class PageUtil {
private PageUtil() {
}
private static final long DOWNGRADE_THRESHOLD = Boolean.getBoolean("org.jboss.errai.debugmode") ?
TimeUnit.SECONDS.toNanos(1600) : TimeUnit.SECONDS.toNanos(10);
private static final String tempDir = System.getProperty("java.io.tmpdir");
public static String getPageFileName(final MessageQueue queue) {
return tempDir + "/queuecache/" + queue.getSession().getSessionId().replaceAll("\\-", "_");
}
public static File getOrCreatePageFile(final MessageQueue queue) throws IOException {
final File pageFile = new File(getPageFileName(queue));
if (!pageFile.exists()) {
pageFile.getParentFile().mkdirs();
pageFile.createNewFile();
pageFile.deleteOnExit();
}
return pageFile;
}
public static void writeToPageFile(final MessageQueue queue, final InputStream inputStream, final boolean append) {
try {
final OutputStream outputStream
= new BufferedOutputStream(new FileOutputStream(getOrCreatePageFile(queue), append));
int read;
while ((read = inputStream.read()) != -1) outputStream.write(read);
outputStream.flush();
outputStream.close();
}
catch (IOException e) {
throw new RuntimeException("paging error", e);
}
}
public static boolean pageWaitingToDisk(final MessageQueue queue) {
synchronized (queue.getPageLock()) {
try {
final boolean alreadyPaged = queue.isPaged();
final OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(getOrCreatePageFile(queue), alreadyPaged));
final ByteWriteAdapter writeAdapter = new OutputStreamWriteAdapter(outputStream);
queue.getBuffer().read(writeAdapter, queue.getBufferColor());
outputStream.flush();
outputStream.close();
queue.setPaged(true);
return alreadyPaged;
}
catch (IOException e) {
throw new RuntimeException("paging error", e);
}
}
}
public static void readInPageFile(final MessageQueue queue,
final ByteWriteAdapter outputStream,
final BufferFilter callback) {
synchronized (queue.getPageLock()) {
try {
if (queue.isPaged()) {
final File pageFile = new File(getPageFileName(queue));
if (!pageFile.exists()) {
queue.setPaged(false);
return;
}
final InputStream inputStream = new BufferedInputStream(new FileInputStream(pageFile));
callback.before(outputStream);
int read;
while ((read = inputStream.read()) != -1) {
outputStream.write(callback.each(read, outputStream));
}
inputStream.close();
callback.after(outputStream);
queue.setPaged(false);
}
}
catch (Exception e) {
throw new RuntimeException("paging error", e);
}
}
}
public static void discardPageData(final MessageQueue queue) {
if (queue.isPaged()) {
File pageFile = new File(getPageFileName(queue));
if (pageFile.exists()) {
pageFile.delete();
}
}
}
public static boolean pageIfStraddling(final MessageQueue queue) {
if (queue.getDeliveryHandler() instanceof Pageable) {
if (((nanoTime() - queue.getLastTransmissionTime()) > DOWNGRADE_THRESHOLD)) {
((Pageable) queue.getDeliveryHandler()).pageOut(queue);
return true;
}
}
return false;
}
}