Search in sources :

Example 1 with ConflationKey

use of org.apache.geode.distributed.internal.ConflationKey in project geode by apache.

the class Connection method addToQueue.

private boolean addToQueue(ByteBuffer buffer, DistributionMessage msg, boolean force) throws ConnectionException {
    final DMStats stats = this.owner.getConduit().stats;
    long start = DistributionStats.getStatTime();
    try {
        ConflationKey ck = null;
        if (msg != null) {
            ck = msg.getConflationKey();
        }
        Object objToQueue = null;
        // if we can conflate delay the copy to see if we can reuse
        // an already allocated buffer.
        final int newBytes = buffer.remaining();
        // to fix bug 34832
        final int origBufferPos = buffer.position();
        if (ck == null || !ck.allowsConflation()) {
            // do this outside of sync for multi thread perf
            ByteBuffer newbb = ByteBuffer.allocate(newBytes);
            newbb.put(buffer);
            newbb.flip();
            objToQueue = newbb;
        }
        synchronized (this.outgoingQueue) {
            if (this.disconnectRequested) {
                buffer.position(origBufferPos);
                // we have given up so just drop this message.
                throw new ConnectionException(LocalizedStrings.Connection_FORCED_DISCONNECT_SENT_TO_0.toLocalizedString(this.remoteAddr));
            }
            if (!force && !this.asyncQueuingInProgress) {
                // reset buffer since we will be sending it. This fixes bug 34832
                buffer.position(origBufferPos);
                // the pusher emptied the queue so don't add since we are not forced to.
                return false;
            }
            boolean didConflation = false;
            if (ck != null) {
                if (ck.allowsConflation()) {
                    objToQueue = ck;
                    Object oldValue = this.conflatedKeys.put(ck, ck);
                    if (oldValue != null) {
                        ConflationKey oldck = (ConflationKey) oldValue;
                        ByteBuffer oldBuffer = oldck.getBuffer();
                        // need to always do this to allow old buffer to be gc'd
                        oldck.setBuffer(null);
                        // remove it
                        if (this.outgoingQueue.getLast() == oldck) {
                            this.outgoingQueue.removeLast();
                        }
                        int oldBytes = oldBuffer.remaining();
                        this.queuedBytes -= oldBytes;
                        stats.incAsyncQueueSize(-oldBytes);
                        stats.incAsyncConflatedMsgs();
                        didConflation = true;
                        if (oldBuffer.capacity() >= newBytes) {
                            // copy new buffer into oldBuffer
                            oldBuffer.clear();
                            oldBuffer.put(buffer);
                            oldBuffer.flip();
                            ck.setBuffer(oldBuffer);
                        } else {
                            // old buffer was not large enough
                            oldBuffer = null;
                            ByteBuffer newbb = ByteBuffer.allocate(newBytes);
                            newbb.put(buffer);
                            newbb.flip();
                            ck.setBuffer(newbb);
                        }
                    } else {
                        // no old buffer so need to allocate one
                        ByteBuffer newbb = ByteBuffer.allocate(newBytes);
                        newbb.put(buffer);
                        newbb.flip();
                        ck.setBuffer(newbb);
                    }
                } else {
                    // just forget about having a conflatable operation
                    /* Object removedVal = */
                    this.conflatedKeys.remove(ck);
                }
            }
            {
                long newQueueSize = newBytes + this.queuedBytes;
                if (newQueueSize > this.asyncMaxQueueSize) {
                    logger.warn(LocalizedMessage.create(LocalizedStrings.Connection_QUEUED_BYTES_0_EXCEEDS_MAX_OF_1_ASKING_SLOW_RECEIVER_2_TO_DISCONNECT, new Object[] { newQueueSize, this.asyncMaxQueueSize, this.remoteAddr }));
                    stats.incAsyncQueueSizeExceeded(1);
                    disconnectSlowReceiver();
                    // reset buffer since we will be sending it
                    buffer.position(origBufferPos);
                    return false;
                }
            }
            this.outgoingQueue.addLast(objToQueue);
            this.queuedBytes += newBytes;
            stats.incAsyncQueueSize(newBytes);
            if (!didConflation) {
                stats.incAsyncQueuedMsgs();
            }
            return true;
        }
    } finally {
        if (DistributionStats.enableClockStats) {
            stats.incAsyncQueueAddTime(DistributionStats.getStatTime() - start);
        }
    }
}
Also used : DMStats(org.apache.geode.distributed.internal.DMStats) ConflationKey(org.apache.geode.distributed.internal.ConflationKey) ByteBuffer(java.nio.ByteBuffer)

Example 2 with ConflationKey

use of org.apache.geode.distributed.internal.ConflationKey in project geode by apache.

the class Connection method takeFromOutgoingQueue.

private ByteBuffer takeFromOutgoingQueue() throws InterruptedException {
    ByteBuffer result = null;
    final DMStats stats = this.owner.getConduit().stats;
    long start = DistributionStats.getStatTime();
    try {
        synchronized (this.outgoingQueue) {
            if (this.disconnectRequested) {
                // don't bother with anymore work since we are done
                this.asyncQueuingInProgress = false;
                this.outgoingQueue.notifyAll();
                return null;
            }
            // Object o = this.outgoingQueue.poll();
            do {
                if (this.outgoingQueue.isEmpty()) {
                    break;
                }
                Object o = this.outgoingQueue.removeFirst();
                if (o == null) {
                    break;
                }
                if (o instanceof ConflationKey) {
                    result = ((ConflationKey) o).getBuffer();
                    if (result != null) {
                        this.conflatedKeys.remove(o);
                    } else {
                        // queue so we just need to skip this entry
                        continue;
                    }
                } else {
                    result = (ByteBuffer) o;
                }
                int newBytes = result.remaining();
                this.queuedBytes -= newBytes;
                stats.incAsyncQueueSize(-newBytes);
                stats.incAsyncDequeuedMsgs();
            } while (result == null);
            if (result == null) {
                this.asyncQueuingInProgress = false;
                this.outgoingQueue.notifyAll();
            }
        }
        return result;
    } finally {
        if (DistributionStats.enableClockStats) {
            stats.incAsyncQueueRemoveTime(DistributionStats.getStatTime() - start);
        }
    }
}
Also used : DMStats(org.apache.geode.distributed.internal.DMStats) ConflationKey(org.apache.geode.distributed.internal.ConflationKey) ByteBuffer(java.nio.ByteBuffer)

Aggregations

ByteBuffer (java.nio.ByteBuffer)2 ConflationKey (org.apache.geode.distributed.internal.ConflationKey)2 DMStats (org.apache.geode.distributed.internal.DMStats)2