2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl;
10 import static java.util.Objects.requireNonNull;
12 import io.netty.channel.ChannelFuture;
13 import io.netty.channel.ChannelHandlerContext;
14 import io.netty.channel.ChannelInboundHandlerAdapter;
15 import org.opendaylight.yangtools.yang.binding.Notification;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
20 * A best-effort output limiter. It does not provide any fairness, and acts as a blocking gate-keeper
21 * for a sessions' channel.
24 * This class is thread-safe.
26 public final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
27 private static final Logger LOG = LoggerFactory.getLogger(ChannelOutputLimiter.class);
28 private final BGPSessionImpl session;
29 private volatile boolean blocked;
31 ChannelOutputLimiter(final BGPSessionImpl session) {
32 this.session = requireNonNull(session);
35 private void ensureWritable() {
37 LOG.trace("Blocked slow path tripped on session {}", session);
41 LOG.debug("Waiting for session {} to become writable", session);
44 } catch (final InterruptedException e) {
45 throw new IllegalStateException("Interrupted while waiting for channel to come back", e);
49 LOG.debug("Resuming write on session {}", session);
54 public void write(final Notification<?> msg) {
59 ChannelFuture writeAndFlush(final Notification<?> msg) {
61 return session.writeAndFlush(msg);
69 public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception {
70 final boolean w = ctx.channel().isWritable();
74 LOG.debug("Writes on session {} {}", session, w ? "unblocked" : "blocked");
81 super.channelWritabilityChanged(ctx);
85 public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
91 super.channelInactive(ctx);