Conserver l'état dans un Netty ChannelHandler
-
25-10-2019 - |
Question
La documentation Netty suggère l'utilisation de variables d'instance dans ChannelHandlers de garder une trace de l'état du canal. Il ne mentionne pas que vous devez utiliser des variables volatiles ou utiliser toute autre technique de synchronisation pour assurer qu'il ya une vision cohérente entre les threads.
Par exemple en utilisant ce gestionnaire sur une base par connexion:
class Handler extends SimpleChannelUpstreamHandler {
int count = 0;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
++count;
}
}
Je suppose que beaucoup de fils différents d'un pool de threads Netty serait d'appeler cette méthode, mais pas en même temps, et pourrait voir une vue incompatible, ce qui un nombre inexact.
Est-ce le cas? ou est-il une sorte de synchronisation passe à l'intérieur de Netty qui provoquerait l'écriture au champ de comptage pour être vidées?
La solution
Si vous ne disposez pas d'un exécuteur testamentaire dans votre pipeline, et exécutez vos gestionnaires uniquement dans les threads de travail I / O, alors vous êtes bien en garantie Netty qu'une instance de pipeline donnée est toujours appelé à partir du même thread de travail .
Si vous ajoutez un gestionnaire d'exécution à votre pipeline, alors vous êtes ok si vous utilisez le OrderedMemoryAwareThreadPoolExecutor Netty.
Si vous accédez à votre pipeline à partir d'un fil non Netty, ou si vous avez un non-OrderedMemoryAwareThreadPoolExecutor dans votre pipeline alors vous avez besoin de synchronisation.
Je recommande de prendre un coup d'oeil à travers les discussions suivantes sur les archives du forum utilisateur Netty.
Autres conseils
Lorsque vous créez un ChannelPipeline
Netty si vous ajoutez le même instance de votre Handler
à tous les canaux alors oui, plusieurs threads lire / modifier vos données.
Si vous créez une nouvelle instance de Handler
par canal dans votre pipeline comme indiqué ci-dessous alors vous êtes en sécurité, que un fil accéder au gestionnaire dans la section pipeline à un moment-là.
ChannelPipeline p = Channels.pipeline();
pipeline.addLast("handler", new Handler());
Jetez aussi un coup d'œil à Netty ChannelLocal , comme son ThreadLocal
java et vous pouvez définir l'état sur une base par canal