use of org.apache.activemq.artemis.core.server.LargeServerMessage in project activemq-artemis by apache.
the class JournalStorageManager method parseLargeMessage.
@Override
protected /**
* @param messages
* @param buff
* @return
* @throws Exception
*/
LargeServerMessage parseLargeMessage(final Map<Long, Message> messages, final ActiveMQBuffer buff) throws Exception {
LargeServerMessage largeMessage = createLargeMessage();
LargeMessagePersister.getInstance().decode(buff, largeMessage);
if (largeMessage.containsProperty(Message.HDR_ORIG_MESSAGE_ID)) {
// for compatibility: couple with old behaviour, copying the old file to avoid message loss
long originalMessageID = largeMessage.getLongProperty(Message.HDR_ORIG_MESSAGE_ID);
SequentialFile currentFile = createFileForLargeMessage(largeMessage.getMessageID(), true);
if (!currentFile.exists()) {
SequentialFile linkedFile = createFileForLargeMessage(originalMessageID, true);
if (linkedFile.exists()) {
linkedFile.copyTo(currentFile);
linkedFile.close();
}
}
currentFile.close();
}
return largeMessage;
}
use of org.apache.activemq.artemis.core.server.LargeServerMessage in project activemq-artemis by apache.
the class ServerSessionPacketHandler method sendLarge.
// Large Message is part of the core protocol, we have these functions here as part of Packet handler
private void sendLarge(final Message message) throws Exception {
// need to create the LargeMessage before continue
long id = storageManager.generateID();
LargeServerMessage largeMsg = storageManager.createLargeMessage(id, message);
if (logger.isTraceEnabled()) {
logger.trace("sendLarge::" + largeMsg);
}
if (currentLargeMessage != null) {
ActiveMQServerLogger.LOGGER.replacingIncompleteLargeMessage(currentLargeMessage.getMessageID());
}
currentLargeMessage = largeMsg;
}
use of org.apache.activemq.artemis.core.server.LargeServerMessage in project activemq-artemis by apache.
the class PagingStoreImpl method start.
@Override
public void start() throws Exception {
lock.writeLock().lock();
try {
if (running) {
// need to be ignored
return;
} else {
running = true;
firstPageId = Integer.MAX_VALUE;
// There are no files yet on this Storage. We will just return it empty
if (fileFactory != null) {
currentPageId = 0;
if (currentPage != null) {
currentPage.close(false);
}
currentPage = null;
List<String> files = fileFactory.listFiles("page");
numberOfPages = files.size();
for (String fileName : files) {
final int fileId = PagingStoreImpl.getPageIdFromFileName(fileName);
if (fileId > currentPageId) {
currentPageId = fileId;
}
if (fileId < firstPageId) {
firstPageId = fileId;
}
}
if (currentPageId != 0) {
currentPage = createPage(currentPageId);
currentPage.open();
List<PagedMessage> messages = currentPage.read(storageManager);
LivePageCache pageCache = new LivePageCacheImpl(currentPage);
for (PagedMessage msg : messages) {
pageCache.addLiveMessage(msg);
if (msg.getMessage().isLargeMessage()) {
// We have to do this since addLIveMessage will increment an extra one
((LargeServerMessage) msg.getMessage()).decrementDelayDeletionCount();
}
}
currentPage.setLiveCache(pageCache);
currentPageSize.set(currentPage.getSize());
cursorProvider.addPageCache(pageCache);
}
// We will not mark it for paging if there's only a single empty file
if (currentPage != null && !(numberOfPages == 1 && currentPage.getSize() == 0)) {
startPaging();
}
}
}
} finally {
lock.writeLock().unlock();
}
}
use of org.apache.activemq.artemis.core.server.LargeServerMessage in project activemq-artemis by apache.
the class PagingStoreImpl method page.
@Override
public boolean page(Message message, final Transaction tx, RouteContextList listCtx, final ReadLock managerLock) throws Exception {
if (!running) {
throw new IllegalStateException("PagingStore(" + getStoreName() + ") not initialized");
}
boolean full = isFull();
if (addressFullMessagePolicy == AddressFullMessagePolicy.DROP || addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) {
if (full) {
if (!printedDropMessagesWarning) {
printedDropMessagesWarning = true;
ActiveMQServerLogger.LOGGER.pageStoreDropMessages(storeName, sizeInBytes.get(), maxSize);
}
if (message.isLargeMessage()) {
((LargeServerMessage) message).deleteFile();
}
if (addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) {
throw ActiveMQMessageBundle.BUNDLE.addressIsFull(address.toString());
}
// Address is full, we just pretend we are paging, and drop the data
return true;
} else {
return false;
}
} else if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK) {
return false;
}
// We need to ensure a read lock, as depage could change the paging state
lock.readLock().lock();
try {
// First check done concurrently, to avoid synchronization and increase throughput
if (!paging) {
return false;
}
} finally {
lock.readLock().unlock();
}
if (managerLock != null) {
managerLock.lock();
}
try {
lock.writeLock().lock();
try {
if (!paging) {
return false;
}
message.setAddress(address);
final long transactionID = tx == null ? -1 : tx.getID();
PagedMessage pagedMessage = new PagedMessageImpl(message, routeQueues(tx, listCtx), transactionID);
if (message.isLargeMessage()) {
((LargeServerMessage) message).setPaged();
}
int bytesToWrite = pagedMessage.getEncodeSize() + Page.SIZE_RECORD;
if (currentPageSize.addAndGet(bytesToWrite) > pageSize && currentPage.getNumberOfMessages() > 0) {
// Make sure nothing is currently validating or using currentPage
openNewPage();
currentPageSize.addAndGet(bytesToWrite);
}
if (tx != null) {
installPageTransaction(tx, listCtx);
}
// the apply counter will make sure we write a record on journal
// especially on the case for non transactional sends and paging
// doing this will give us a possibility of recovering the page counters
long persistentSize = pagedMessage.getPersistentSize() > 0 ? pagedMessage.getPersistentSize() : 0;
applyPageCounters(tx, getCurrentPage(), listCtx, persistentSize);
currentPage.write(pagedMessage);
if (tx == null && syncNonTransactional && message.isDurable()) {
sync();
}
if (logger.isTraceEnabled()) {
logger.trace("Paging message " + pagedMessage + " on pageStore " + this.getStoreName() + " pageNr=" + currentPage.getPageId());
}
return true;
} finally {
lock.writeLock().unlock();
}
} finally {
if (managerLock != null) {
managerLock.unlock();
}
}
}
use of org.apache.activemq.artemis.core.server.LargeServerMessage in project activemq-artemis by apache.
the class StompSession method sendInternalLarge.
public void sendInternalLarge(CoreMessage message, boolean direct) throws Exception {
int headerSize = message.getHeadersAndPropertiesEncodeSize();
if (headerSize >= connection.getMinLargeMessageSize()) {
throw BUNDLE.headerTooBig();
}
StorageManager storageManager = ((ServerSessionImpl) session).getStorageManager();
long id = storageManager.generateID();
LargeServerMessage largeMessage = storageManager.createLargeMessage(id, message);
ActiveMQBuffer body = message.getReadOnlyBodyBuffer();
byte[] bytes = new byte[body.readableBytes()];
body.readBytes(bytes);
largeMessage.addBytes(bytes);
largeMessage.releaseResources();
largeMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, bytes.length);
session.send(largeMessage, direct);
largeMessage = null;
}
Aggregations