/** * Remove all references to the channel. 1) the map of a channel (socket) to its interests. 2) the * map of interests to its channels. * * <p>As each interest is removed inform all channels having a similar interest. * * @param sourceCtx */ public void unregister(final ChannelHandlerContext sourceCtx) { final SocketAddress key = sourceCtx.channel().remoteAddress(); majorLogger.info("unregister channel {}", key); final Interest.ChannelInterestSet channelInterestSet = this.channelInterestMap.remove(key); if (channelInterestSet == null) { majorLogger.warn( "nothing to unregister in interest map: {}", this.channelInterestMap.keySet()); return; } final String trackingGuid = UUID.randomUUID().toString(); majorLogger.warn("no interested channel set"); for (final Interest interest : channelInterestSet.getInterestList()) { if (!this.interestedChannelMap.containsKey(interest)) { continue; } final Interest.InterestedChannelSet interestedChannelSet = this.interestedChannelMap.get(interest); interestedChannelSet.removeItem(sourceCtx, interest); majorLogger.info("unregistered interest {}", interest); // this.interestedChannelMap.put(interest, interestedChannelSet); // an implicit DISINTEREST message will be sent to all interested channels final MetaLinkMsg.Edit.Builder editBuilder = MetaLinkMsg.Edit.newBuilder() .addMode(MetaLinkMsg.Edit.EditMode.DISINTEREST) .setEditMode(MetaLinkMsg.Edit.EditMode.DISINTEREST) .setGuid(trackingGuid) .setSequence(sequenceNumber.incrementAndGet()) .addAllTopic(interest.getTopic()) .addOrigin(sourceCtx.channel().remoteAddress().toString()) .addOrigin(METALINK_BRIDGE_NAME); final MetaLinkMsg.Edit disinterestMsg = editBuilder.build(); majorLogger.trace("expressing disinterest to all channels except source"); for (final Map.Entry<SocketAddress, Interest.ChannelInterestSet> entry : this.channelInterestMap.entrySet()) { final ChannelHandlerContext ctx = entry.getValue().context; if (isSameChannel(ctx, sourceCtx)) { continue; } majorLogger.trace("disinterest {} to {}", trackingGuid, ctx.channel().remoteAddress()); ctx.write(disinterestMsg); ctx.flush(); detailLogger.info("message sent:\n{}", disinterestMsg); } } }
/** * Drop the interest for the specified socket. * * @param ctx * @param interest */ public void setDisinterest(final ChannelHandlerContext ctx, final Interest interest) { majorLogger.info("set {} expression of disinterest {}:{}", ctx, interest); final SocketAddress key = ctx.channel().remoteAddress(); if (this.channelInterestMap.containsKey(key)) { final Interest.ChannelInterestSet interestSet = this.channelInterestMap.get(key); interestSet.removeItem(ctx, interest); // this.channelInterestMap.put(key, interestSet); } if (this.interestedChannelMap.containsKey(interest)) { final Interest.InterestedChannelSet channelSet = this.interestedChannelMap.get(interest); channelSet.removeItem(ctx, interest); // this.interestedChannelMap.put(interest, channelSet); } }
/** * Only registered channels may have interest set. Once interest has been set all post messages * with matching topic and will be sent to the channel. * * @param ctx the channel * @param interest the topic */ public void setInterest(final ChannelHandlerContext ctx, final Interest interest) { majorLogger.info("set expression of interest [{}]", interest); final SocketAddress key = ctx.channel().remoteAddress(); if (!this.channelInterestMap.containsKey(key)) { majorLogger.error("can not express interest from an unregistered client"); // write a notice, to whom? return; } final Interest.ChannelInterestSet interestSet = this.channelInterestMap.get(key); interestSet.addItem(ctx, interest); final Interest.InterestedChannelSet channelSet; if ((!this.interestedChannelMap.containsKey(interest)) || (this.interestedChannelMap.get(interest) == null)) { channelSet = new Interest.InterestedChannelSet(interest); this.interestedChannelMap.put(interest, channelSet); } else { channelSet = this.interestedChannelMap.get(interest); } channelSet.addItem(ctx, interest); }