redis / lettuce

Advanced Java Redis client for thread-safe sync, async, and reactive usage. Supports Cluster, Sentinel, Pipelining, and codecs.
https://lettuce.io
MIT License
5.3k stars 947 forks source link

Stateful redis cluster pubsub is not working #2850

Open jigneshmpatel opened 1 month ago

jigneshmpatel commented 1 month ago

Bug Report

Current Behavior

The pub-sub for the cluster is not working and complaint about the encoder, method. I have tested this with the following versions of netty 4.1.109.Final</io.netty.version> 4.1.59.Final</io.netty.version>

Stack trace ```java java.lang.NoSuchMethodError: io.netty.util.CharsetUtil.encoder(Ljava/nio/charset/Charset;)Ljava/nio/charset/CharsetEncoder; ```

Input Code

Input Code ```java public void publishToEncounterCheckoutTimeChannel(CacheConstants cacheConstants, String key, String checkoutTimeInSeconds) { String redisKey = this.getDelimiter().add(cacheConstants.getCacheName()).add(key).toString(); StatefulRedisClusterPubSubConnection connection= connectToRedisCluster.getClusterPubSubConnection(); RedisClusterPubSubCommands commands = connection.sync(); commands.publish("EncounterCheckoutTimeChannel",redisKey ); // The may be in seconds commands.expire(redisKey ,Long.parseLong(checkoutTimeInSeconds)); } public StatefulRedisClusterPubSubConnection getClusterPubSubConnection() { clusterClient = this.establishConnection(); return clusterClient.connectPubSub(); } //following works as I am using same setup with regular(NON Pubsub) setups private RedisClusterClient establishConnection() { String profileName = configProperties.getProperty("buildProfile"); logger.info("Profile Name :- {}", profileName); char authpswdcharArray[] = configProperties.getProperty("authPassword").toCharArray(); logger.debug("authPasswordArray:"+authpswdcharArray.toString()); logger.debug("ClusterHost :- {}", configProperties.getProperty("ECclusterhost")); boolean sslFlag = true; if(profileName.equalsIgnoreCase("standalone")){ sslFlag = false; } RedisURI redisURI = RedisURI.Builder.redis(configProperties.getProperty("ECclusterhost"), Integer.parseInt(configProperties.getProperty("ECclusterport"))).withPassword(authpswdcharArray).withSsl(sslFlag).build(); clusterClient = RedisClusterClient.create(redisURI); logger.debug("clusterClient got created :- {}", clusterClient); return clusterClient; } ```

Expected behavior/code

Environment

Possible Solution

There should not be an error for the encoder method as I believe I am using the appropriate version of netty. StatefulRedisClusterPubSubConnection should work.

Additional context

jigneshmpatel commented 1 month ago

Initially, I used to have a following dependencies defined in pom.xml

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-common</artifactId>
            <version>${io.netty.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport</artifactId>
            <version>${io.netty.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-handler</artifactId>
            <version>${io.netty.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-resolver-dns</artifactId>
            <version>${io.netty.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-codec-dns</artifactId>
            <version>${io.netty.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-resolver</artifactId>
            <version>${io.netty.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-buffer</artifactId>
            <version>${io.netty.version}</version>
            <scope>runtime</scope>
        </dependency>

but replacing it with the following worked.

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>${io.netty.version}</version>
            <scope>compile</scope>
        </dependency>

I didn't like to import all, so if there is a better solution please let me know.

tishun commented 4 days ago

Hey @jigneshmpatel ,

Initially, I used to have a following dependencies defined in pom.xml

unfortunately it is very hard to give out a recommendation on this, as it is quite specific on the project and the environment you are using. The initial issue seems to indicate that a required dependency is missing (or with the wrong version), so it is definitely a maven configuration issue. Using the netty-all package is valid in some situations and could be a problem in others ...

So as I said - quite specific to the project and environment.

I didn't like to import all, so if there is a better solution please let me know.

What is your concern with importing netty this way?

jigneshmpatel commented 3 days ago

Hey @jigneshmpatel ,

Initially, I used to have a following dependencies defined in pom.xml

unfortunately it is very hard to give out a recommendation on this, as it is quite specific on the project and the environment you are using. The initial issue seems to indicate that a required dependency is missing (or with the wrong version), so it is definitely a maven configuration issue. Using the netty-all package is valid in some situations and could be a problem in others ...

So as I said - quite specific to the project and environment.

I didn't like to import all, so if there is a better solution please let me know.

What is your concern with importing netty this way? It is the same concern as you mentioned previously sometime importing all creates problems. However, it worked for me, so I used netty-alll.