/** * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowplugin.openflow.md.queue; import com.google.common.base.Preconditions; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor; import org.opendaylight.openflowplugin.api.openflow.md.queue.HarvesterHandle; import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueItem; import org.opendaylight.openflowplugin.api.openflow.md.queue.QueueKeeper; import org.opendaylight.openflowplugin.api.openflow.md.queue.WaterMarkListener; import org.opendaylight.openflowplugin.api.openflow.md.util.PollableQueuesPriorityZipper; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * QueueKeeper implementation based on {@link OfHeader} */ public class QueueKeeperFairImpl implements QueueKeeper<OfHeader> { private static final Logger LOG = LoggerFactory .getLogger(QueueKeeperFairImpl.class); private Queue<QueueItem<OfHeader>> queueDefault; private BlockingQueue<QueueItem<OfHeader>> queueUnordered; private AutoCloseable pollRegistration; private int capacity = 5000; private HarvesterHandle harvesterHandle; private PollableQueuesPriorityZipper<QueueItem<OfHeader>> queueZipper; private WaterMarkListener waterMarkListener; @Override public void close() throws Exception { Preconditions.checkNotNull(pollRegistration, "pollRegistration not available"); pollRegistration.close(); } @Override public void push(OfHeader message, ConnectionConductor conductor, QueueKeeper.QueueType queueType) { QueueItemOFImpl qItem = new QueueItemOFImpl(message, conductor, queueType); boolean enqueued = false; switch (queueType) { case DEFAULT: enqueued = queueDefault.offer(qItem); break; case UNORDERED: enqueued = queueUnordered.offer(qItem); break; default: LOG.warn("unsupported queue type: [{}] -> dropping message [{}]", queueType, message.getImplementedInterface()); } if (enqueued) { harvesterHandle.ping(); } else { LOG.debug("ingress throttling is use -> {}", queueType); } // if enqueueing fails -> message will be dropped } /** * @return the ingressQueue */ @Override public QueueItem<OfHeader> poll() { return queueZipper.poll(); } /** * @param processingRegistration * the processingRegistration to set */ @Override public void setPollRegistration(AutoCloseable processingRegistration) { this.pollRegistration = processingRegistration; } /** * @param capacity * the capacity of internal blocking queue */ public void setCapacity(int capacity) { this.capacity = capacity; } /** * init blocking queue */ public void init() { Preconditions.checkNotNull(waterMarkListener); queueUnordered = new ArrayBlockingQueue<>(capacity); queueDefault = new ArrayBlockingQueue<>(capacity); WrapperQueueImpl<QueueItem<OfHeader>> wrapperQueue = new WrapperQueueImpl<>( capacity, queueDefault, waterMarkListener); queueZipper = new PollableQueuesPriorityZipper<>(); queueZipper.addSource(queueUnordered); queueZipper.setPrioritizedSource(wrapperQueue); } public void setWaterMarkListener(WaterMarkListener waterMarkListener) { this.waterMarkListener = waterMarkListener; } /** * @param harvesterHandle harvester handle */ public void setHarvesterHandle(HarvesterHandle harvesterHandle) { this.harvesterHandle = harvesterHandle; } }