/** * Create a channel based on the provided {@link MessageGroupQueue}. * @param messageGroupQueue the {@link MessageGroupQueue} to use. * @since 5.0 */ public PriorityChannel(MessageGroupQueue messageGroupQueue) { super(messageGroupQueue); this.upperBound = new UpperBound(0); this.useMessageStore = true; }
@Override public int getRemainingCapacity() { return this.upperBound.availablePermits(); }
@Override public Message<?> removeMessage(UUID key) { if (key != null) { Message<?> message = this.idToMessage.remove(key); if (message != null) { this.individualUpperBound.release(); } return message; } else { return null; } }
upperBound = new UpperBound(this.groupCapacity); for (Message<?> message : messages) { upperBound.tryAcquire(-1); group.add(message); for (Message<?> message : messages) { lock.unlock(); if (!upperBound.tryAcquire(this.upperBoundTimeout)) { unlocked = true; throw outOfCapacityException;
@Override public <T> Message<T> addMessage(Message<T> message) { this.isUsed = true; if (!this.individualUpperBound.tryAcquire(this.upperBoundTimeout)) { throw new MessagingException(this.getClass().getSimpleName() + " was out of capacity (" + this.individualCapacity + "), try constructing it with a larger capacity."); } UUID id = message.getHeaders().getId(); Assert.notNull(id, "ID header must not be null"); this.idToMessage.put(id, message); return message; }
upperBound = new UpperBound(this.groupCapacity); for (Message<?> message : messages) { upperBound.tryAcquire(-1); group.add(message); for (Message<?> message : messages) { lock.unlock(); if (!upperBound.tryAcquire(this.upperBoundTimeout)) { unlocked = true; throw outOfCapacityException;
@Override protected boolean doSend(Message<?> message, long timeout) { if (!this.upperBound.tryAcquire(timeout)) { return false; } if (!this.useMessageStore) { return super.doSend(new MessageWrapper(message), 0); } else { return super.doSend(message, 0); } }
@Override public void removeMessageGroup(Object groupId) { Lock lock = this.lockRegistry.obtain(groupId); try { lock.lockInterruptibly(); try { MessageGroup messageGroup = this.groupIdToMessageGroup.remove(groupId); if (messageGroup != null) { UpperBound upperBound = this.groupToUpperBound.remove(groupId); Assert.state(upperBound != null, "'upperBound' must not be null."); upperBound.release(this.groupCapacity); } } finally { lock.unlock(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new MessagingException("Interrupted while obtaining lock", e); } }
/** * Creates a SimpleMessageStore with a maximum size limited by the given capacity, * the timeout in millisecond to wait for the empty slot in the store and LockRegistry * for the message group operations concurrency. * @param individualCapacity The message capacity. * @param groupCapacity The capacity of each group. * @param upperBoundTimeout The time to wait if the store is at max capacity * @param lockRegistry The lock registry. * @since 4.3 */ public SimpleMessageStore(int individualCapacity, int groupCapacity, long upperBoundTimeout, LockRegistry lockRegistry) { super(false); Assert.notNull(lockRegistry, "The LockRegistry cannot be null"); this.individualUpperBound = new UpperBound(individualCapacity); this.individualCapacity = individualCapacity; this.groupCapacity = groupCapacity; this.lockRegistry = lockRegistry; this.upperBoundTimeout = upperBoundTimeout; }
@Override public <T> Message<T> addMessage(Message<T> message) { this.isUsed = true; if (!this.individualUpperBound.tryAcquire(this.upperBoundTimeout)) { throw new MessagingException(this.getClass().getSimpleName() + " was out of capacity (" + this.individualCapacity + "), try constructing it with a larger capacity."); } UUID id = message.getHeaders().getId(); Assert.notNull(id, "ID header must not be null"); this.idToMessage.put(id, message); return message; }
@Override public int getRemainingCapacity() { return this.upperBound.availablePermits(); }
@Override protected Message<?> doReceive(long timeout) { Message<?> message = super.doReceive(timeout); if (message != null) { if (!this.useMessageStore) { message = ((MessageWrapper) message).getRootMessage(); } this.upperBound.release(); } return message; }
/** * Create a channel with the specified queue capacity. If the capacity * is a non-positive value, the queue will be unbounded. Message priority * will be determined by the provided {@link Comparator}. If the comparator * is <code>null</code>, the priority will be based upon the value of * {@link IntegrationMessageHeaderAccessor#getPriority()}. * * @param capacity The capacity. * @param comparator The comparator. */ public PriorityChannel(int capacity, @Nullable Comparator<Message<?>> comparator) { super(new PriorityBlockingQueue<>(11, new SequenceFallbackComparator(comparator))); this.upperBound = new UpperBound(capacity); this.useMessageStore = false; }
@Override protected boolean doSend(Message<?> message, long timeout) { if (!this.upperBound.tryAcquire(timeout)) { return false; } if (!this.useMessageStore) { return super.doSend(new MessageWrapper(message), 0); } else { return super.doSend(message, 0); } }
public void clearMessageGroup(Object groupId) { Lock lock = this.lockRegistry.obtain(groupId); try { lock.lockInterruptibly(); try { MessageGroup group = this.groupIdToMessageGroup.get(groupId); Assert.notNull(group, "MessageGroup for groupId '" + groupId + "' " + "can not be located while attempting to complete the MessageGroup"); group.clear(); group.setLastModified(System.currentTimeMillis()); UpperBound upperBound = this.groupToUpperBound.get(groupId); Assert.state(upperBound != null, "'upperBound' must not be null."); upperBound.release(this.groupCapacity); } finally { lock.unlock(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new MessagingException("Interrupted while obtaining lock", e); } }
/** * Create a channel based on the provided {@link MessageGroupQueue}. * @param messageGroupQueue the {@link MessageGroupQueue} to use. * @since 5.0 */ public PriorityChannel(MessageGroupQueue messageGroupQueue) { super(messageGroupQueue); this.upperBound = new UpperBound(0); this.useMessageStore = true; }
for (Message<?> messageToRemove : messages) { if (group.remove(messageToRemove)) { upperBound.release(); modified = true;
/** * Creates a SimpleMessageStore with a maximum size limited by the given capacity, * the timeout in millisecond to wait for the empty slot in the store and LockRegistry * for the message group operations concurrency. * @param individualCapacity The message capacity. * @param groupCapacity The capacity of each group. * @param upperBoundTimeout The time to wait if the store is at max capacity * @param lockRegistry The lock registry. * @since 4.3 */ public SimpleMessageStore(int individualCapacity, int groupCapacity, long upperBoundTimeout, LockRegistry lockRegistry) { super(false); Assert.notNull(lockRegistry, "The LockRegistry cannot be null"); this.individualUpperBound = new UpperBound(individualCapacity); this.individualCapacity = individualCapacity; this.groupCapacity = groupCapacity; this.lockRegistry = lockRegistry; this.upperBoundTimeout = upperBoundTimeout; }
@Override public Message<?> removeMessage(UUID key) { if (key != null) { Message<?> message = this.idToMessage.remove(key); if (message != null) { this.individualUpperBound.release(); } return message; } else { return null; } }
/** * Create a channel with the specified queue capacity. If the capacity * is a non-positive value, the queue will be unbounded. Message priority * will be determined by the provided {@link Comparator}. If the comparator * is <code>null</code>, the priority will be based upon the value of * {@link IntegrationMessageHeaderAccessor#getPriority()}. * * @param capacity The capacity. * @param comparator The comparator. */ public PriorityChannel(int capacity, @Nullable Comparator<Message<?>> comparator) { super(new PriorityBlockingQueue<>(11, new SequenceFallbackComparator(comparator))); this.upperBound = new UpperBound(capacity); this.useMessageStore = false; }