-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Labels
type: taskA general taskA general task
Milestone
Description
Bug Report
Current Behavior
When StatefulRedisConnection
is reset, results of subsequent commands are non-deterministic. Results of completely different commands are returned. I extracted minimal example, where there are 2 redis keys: a
->a
and b
->b
. Two parallel threads are reading these two keys in a loop. Then, at some point I reset StatefulRedisConnection
. After that, the result of client.get("a") can be "b" and vice versa.
Input Code
Minimal example:
package test;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import org.junit.Test;
import java.time.Duration;
import java.util.concurrent.CancellationException;
public class LettuceTest {
@Test
public void testParallelExecution() throws InterruptedException {
final RedisURI uri = new RedisURI("127.0.0.1", 6379, Duration.ofSeconds(1));
final StatefulRedisConnection<String, String> conn = RedisClient.create(uri).connect();
final RedisCommands<String, String> sync = conn.sync();
sync.set("a", "a");
sync.set("b", "b");
final Thread a = runThread(sync, "a");
final Thread b = runThread(sync, "b");
a.start();
b.start();
while(a.isAlive() && b.isAlive()) {
Thread.sleep(1000);
conn.reset();
}
throw new IllegalStateException("Threads should not terminate");
}
private Thread runThread(RedisCommands<String, String> async, String key) {
return new Thread(() -> {
while (true) {
try {
final String result = async.get(key);
System.out.println(String.format("Expected %s, received %s", key, result));
if (!key.equals(result)) break;
} catch (CancellationException e) {
// ok
}
}
});
}
}
Environment
- Lettuce version(s): 5.1.2.RELEASE
- Redis version: 5.0.0
Metadata
Metadata
Assignees
Labels
type: taskA general taskA general task