Reload scripts across the whole cluster if one shard is missing the script.
This commit is contained in:
parent
2d697ac8db
commit
1b53f10091
|
@ -64,7 +64,7 @@ public class ClusterLuaScript {
|
||||||
try {
|
try {
|
||||||
return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY));
|
return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY));
|
||||||
} catch (final RedisNoScriptException e) {
|
} catch (final RedisNoScriptException e) {
|
||||||
clusterCommands.scriptLoad(script);
|
reloadScript();
|
||||||
return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY));
|
return clusterCommands.evalsha(sha, scriptOutputType, keys.toArray(STRING_ARRAY), args.toArray(STRING_ARRAY));
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
@ -82,7 +82,7 @@ public class ClusterLuaScript {
|
||||||
try {
|
try {
|
||||||
return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY));
|
return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY));
|
||||||
} catch (final RedisNoScriptException e) {
|
} catch (final RedisNoScriptException e) {
|
||||||
binaryCommands.scriptLoad(script.getBytes(StandardCharsets.UTF_8));
|
reloadScript();
|
||||||
return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY));
|
return binaryCommands.evalsha(sha, scriptOutputType, keys.toArray(BYTE_ARRAY_ARRAY), args.toArray(BYTE_ARRAY_ARRAY));
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
@ -91,4 +91,8 @@ public class ClusterLuaScript {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void reloadScript() {
|
||||||
|
redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptLoad(script));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,24 +90,18 @@ public class ClusterLuaScriptTest extends AbstractRedisClusterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecuteNoScriptException() {
|
public void testExecuteNoScriptException() {
|
||||||
final RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
final String key = "key";
|
||||||
final FaultTolerantRedisCluster mockCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
final String value = "value";
|
||||||
|
|
||||||
final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])";
|
final FaultTolerantRedisCluster redisCluster = getRedisCluster();
|
||||||
final String sha = "abc123";
|
|
||||||
final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE;
|
|
||||||
final List<String> keys = List.of("key");
|
|
||||||
final List<String> values = List.of("value");
|
|
||||||
|
|
||||||
when(commands.scriptLoad(script)).thenReturn(sha);
|
final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", ScriptOutputType.VALUE);
|
||||||
when(commands.evalsha(any(), any(), any(), any()))
|
|
||||||
.thenThrow(new RedisNoScriptException("OH NO"))
|
|
||||||
.thenReturn("OK");
|
|
||||||
|
|
||||||
new ClusterLuaScript(mockCluster, script, scriptOutputType).execute(keys, values);
|
// Remove the scripts created by the CLusterLuaScript constructor
|
||||||
|
redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush());
|
||||||
|
|
||||||
verify(commands, times(2)).scriptLoad(script);
|
assertEquals("OK", script.execute(List.of(key), List.of(value)));
|
||||||
verify(commands, times(2)).evalsha(sha, scriptOutputType, keys.toArray(new String[0]), values.toArray(new String[0]));
|
assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -133,25 +127,17 @@ public class ClusterLuaScriptTest extends AbstractRedisClusterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecuteBinaryNoScriptException() {
|
public void testExecuteBinaryNoScriptException() {
|
||||||
final RedisAdvancedClusterCommands<String, String> stringCommands = mock(RedisAdvancedClusterCommands.class);
|
final String key = "key";
|
||||||
final RedisAdvancedClusterCommands<byte[], byte[]> binaryCommands = mock(RedisAdvancedClusterCommands.class);
|
final String value = "value";
|
||||||
final FaultTolerantRedisCluster mockCluster = RedisClusterHelper.buildMockRedisCluster(stringCommands, binaryCommands);
|
|
||||||
|
|
||||||
final String script = "return redis.call(\"SET\", KEYS[1], ARGV[1])";
|
final FaultTolerantRedisCluster redisCluster = getRedisCluster();
|
||||||
final String sha = "abc123";
|
|
||||||
final ScriptOutputType scriptOutputType = ScriptOutputType.VALUE;
|
|
||||||
final List<byte[]> keys = List.of("key".getBytes(StandardCharsets.UTF_8));
|
|
||||||
final List<byte[]> values = List.of("value".getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
when(stringCommands.scriptLoad(script)).thenReturn(sha);
|
final ClusterLuaScript script = new ClusterLuaScript(redisCluster, "return redis.call(\"SET\", KEYS[1], ARGV[1])", ScriptOutputType.VALUE);
|
||||||
when(binaryCommands.evalsha(any(), any(), any(), any()))
|
|
||||||
.thenThrow(new RedisNoScriptException("OH NO"))
|
|
||||||
.thenReturn("OK".getBytes(StandardCharsets.UTF_8));
|
|
||||||
|
|
||||||
new ClusterLuaScript(mockCluster, script, scriptOutputType).executeBinary(keys, values);
|
// Remove the scripts created by the CLusterLuaScript constructor
|
||||||
|
redisCluster.useCluster(connection -> connection.sync().upstream().commands().scriptFlush());
|
||||||
|
|
||||||
verify(stringCommands).scriptLoad(script);
|
assertArrayEquals("OK".getBytes(StandardCharsets.UTF_8), (byte[])script.executeBinary(List.of(key.getBytes(StandardCharsets.UTF_8)), List.of(value.getBytes(StandardCharsets.UTF_8))));
|
||||||
verify(binaryCommands).scriptLoad(script.getBytes(StandardCharsets.UTF_8));
|
assertEquals(value, redisCluster.withCluster(connection -> connection.sync().get(key)));
|
||||||
verify(binaryCommands, times(2)).evalsha(sha, scriptOutputType, keys.toArray(new byte[0][]), values.toArray(new byte[0][]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue