Fixed mem leak due to caching of object without hasCode (NettyChannelContext

This commit is contained in:
andrea
2015-06-07 17:47:50 +02:00
parent 3ceabfabdd
commit 3f4a5586de
10 changed files with 120 additions and 68 deletions
@@ -37,7 +37,7 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(NettyMQTTHandler.class);
private IMessaging m_messaging;
private final Map<ChannelHandlerContext, NettyChannel> m_channelMapper = new HashMap<ChannelHandlerContext, NettyChannel>();
// private final Map<ChannelHandlerContext, NettyChannel> m_channelMapper = new HashMap<>();
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) {
@@ -54,15 +54,15 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
case PUBREL:
case DISCONNECT:
case PUBACK:
NettyChannel channel;
synchronized(m_channelMapper) {
if (!m_channelMapper.containsKey(ctx)) {
m_channelMapper.put(ctx, new NettyChannel(ctx));
}
channel = m_channelMapper.get(ctx);
}
// NettyChannel channel;
// synchronized(m_channelMapper) {
// if (!m_channelMapper.containsKey(ctx)) {
// m_channelMapper.put(ctx, new NettyChannel(ctx));
// }
// channel = m_channelMapper.get(ctx);
// }
m_messaging.handleProtocolMessage(channel, msg);
m_messaging.handleProtocolMessage(new NettyChannel(ctx), msg);
break;
case PINGREQ:
PingRespMessage pingResp = new PingRespMessage();
@@ -76,13 +76,14 @@ public class NettyMQTTHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
NettyChannel channel = m_channelMapper.get(ctx);
String clientID = (String) channel.getAttribute(NettyChannel.ATTR_KEY_CLIENTID);
m_messaging.lostConnection(channel, clientID);
// NettyChannel channel = m_channelMapper.get(ctx);
// String clientID = (String) channel.getAttribute(NettyChannel.ATTR_KEY_CLIENTID);
String clientID = (String) NettyUtils.getAttribute(ctx, NettyChannel.ATTR_KEY_CLIENTID);
m_messaging.lostConnection(clientID);
ctx.close(/*false*/);
synchronized(m_channelMapper) {
m_channelMapper.remove(ctx);
}
// synchronized(m_channelMapper) {
// m_channelMapper.remove(ctx);
// }
}
public void setMessaging(IMessaging messaging) {
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2012-2014 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package org.eclipse.moquette.server.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
/**
* Some Netty's channels utilities.
*
* @author andrea
*/
public class NettyUtils {
public static Object getAttribute(ChannelHandlerContext channel, AttributeKey<Object> key) {
Attribute<Object> attr = channel.attr(key);
return attr.get();
}
public static void setAttribute(ChannelHandlerContext channel, AttributeKey<Object> key, Object value) {
Attribute<Object> attr = channel.attr(key);
attr.set(value);
}
public static void setIdleTime(ChannelHandlerContext channel, int idleTime) {
if (channel.pipeline().names().contains("idleStateHandler")) {
channel.pipeline().remove("idleStateHandler");
}
if (channel.pipeline().names().contains("idleEventHandler")) {
channel.pipeline().remove("idleEventHandler");
}
channel.pipeline().addFirst("idleStateHandler", new IdleStateHandler(0, 0, idleTime));
channel.pipeline().addAfter("idleStateHandler", "idleEventHandler", new MoquetteIdleTimoutHandler());
}
}
@@ -30,7 +30,7 @@ public interface IMessaging {
void stop();
void lostConnection(ServerChannel session, String clientID);
void lostConnection(String clientID);
void handleProtocolMessage(ServerChannel session, AbstractMessage msg);
}
@@ -561,12 +561,12 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
void processConnectionLost(LostConnectionEvent evt) {
String clientID = evt.clientID;
if (m_clientIDs.containsKey(clientID)) {
if (!m_clientIDs.get(clientID).getSession().equals(evt.session)) {
LOG.info("Received a lost connection with client <{}> for a not matching session", clientID);
return;
}
}
// if (m_clientIDs.containsKey(clientID)) {
// if (!m_clientIDs.get(clientID).getSession().equals(evt.session)) {
// LOG.info("Received a lost connection with client <{}> for a not matching session", clientID);
// return;
// }
// }
//If already removed a disconnect message was already processed for this clientID
if (m_clientIDs.remove(clientID) != null) {
@@ -122,8 +122,8 @@ public class SimpleMessaging implements IMessaging, EventHandler<ValueEvent> {
}
@Override
public void lostConnection(ServerChannel session, String clientID) {
disruptorPublish(new LostConnectionEvent(session, clientID));
public void lostConnection(String clientID) {
disruptorPublish(new LostConnectionEvent(clientID));
}
@Override
@@ -23,11 +23,11 @@ import org.eclipse.moquette.server.ServerChannel;
* @author andrea
*/
public class LostConnectionEvent extends MessagingEvent {
public final ServerChannel session;
// public final ServerChannel session;
public final String clientID;
public LostConnectionEvent(ServerChannel session, String clientID) {
this.session = session;
public LostConnectionEvent(/*ServerChannel session, */String clientID) {
// this.session = session;
this.clientID = clientID;
}
}