Server-Side Scripting
Lua scripting¶
Redisson's RScript object runs a Lua script on the Valkey or Redis side, where it executes atomically. A script runs in one of two modes:
Mode.READ_ONLY- executed as a read operationMode.READ_WRITE- executed as a write operation
The result is decoded according to a ReturnType:
ReturnType.BOOLEAN- boolean typeReturnType.LONG- long typeReturnType.LIST- list of the user-defined typeReturnType.STRING- plain string typeReturnType.VALUE- the user-defined typeReturnType.MAPVALUE- map value type, decoded with the codec's map-value encoder/decoderReturnType.MAPVALUELIST- list of the map value type
eval runs a script directly; the keys and values arguments are exposed inside the script as KEYS and ARGV. For repeated execution, scriptLoad caches the script on every master node and returns its SHA digest, which evalSha then runs without resending the body.
RBucket<String> bucket = redisson.getBucket("foo");
bucket.set("bar");
RScript script = redisson.getScript(StringCodec.INSTANCE);
// run a script directly
String value = script.eval(RScript.Mode.READ_ONLY,
"return redis.call('get', KEYS[1])",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
// cache once, then run by SHA digest
String sha = script.scriptLoad("return redis.call('get', KEYS[1])");
String cached = script.evalSha(RScript.Mode.READ_ONLY,
sha,
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
RScript script = redisson.getScript(StringCodec.INSTANCE);
RFuture<String> valueFuture = script.evalAsync(RScript.Mode.READ_ONLY,
"return redis.call('get', KEYS[1])",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
RFuture<String> shaFuture = script.scriptLoadAsync("return redis.call('get', KEYS[1])");
RFuture<String> cachedFuture = script.evalShaAsync(RScript.Mode.READ_ONLY,
"282297a0228f48cd3fc6a55de6316f31422f5d17",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
RedissonReactiveClient redisson = redissonClient.reactive();
RScriptReactive script = redisson.getScript(StringCodec.INSTANCE);
Mono<String> value = script.eval(RScript.Mode.READ_ONLY,
"return redis.call('get', KEYS[1])",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
Mono<String> sha = script.scriptLoad("return redis.call('get', KEYS[1])");
Mono<String> cached = script.evalSha(RScript.Mode.READ_ONLY,
"282297a0228f48cd3fc6a55de6316f31422f5d17",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
RedissonRxClient redisson = redissonClient.rxJava();
RScriptRx script = redisson.getScript(StringCodec.INSTANCE);
Maybe<String> value = script.eval(RScript.Mode.READ_ONLY,
"return redis.call('get', KEYS[1])",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
Single<String> sha = script.scriptLoad("return redis.call('get', KEYS[1])");
Maybe<String> cached = script.evalSha(RScript.Mode.READ_ONLY,
"282297a0228f48cd3fc6a55de6316f31422f5d17",
RScript.ReturnType.VALUE,
Collections.singletonList("foo"));
Functions¶
Redisson's RFunction object runs a Redis function - a named routine registered inside a library that, like a script, executes atomically on the server. A function runs in one of two modes:
FunctionMode.READ- executed as a read operationFunctionMode.WRITE- executed as a write operation
The result is decoded according to a FunctionResult:
FunctionResult.BOOLEAN- boolean typeFunctionResult.LONG- long typeFunctionResult.LIST- list of the user-defined typeFunctionResult.STRING- plain string typeFunctionResult.VALUE- the user-defined typeFunctionResult.MAPVALUE- map value type, decoded with the codec's map-value encoder/decoderFunctionResult.MAPVALUELIST- list of the map value type
Register a library with load, then invoke one of its functions with call. The keys and values arguments arrive as the function's keys and args parameters.
RFunction function = redisson.getFunction();
// register a library that defines a function
function.load("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
// invoke the function
String value = function.call(FunctionMode.READ, "myfun",
FunctionResult.STRING, Collections.emptyList(), "test");
RFunction function = redisson.getFunction();
RFuture<Void> loadFuture = function.loadAsync("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
RFuture<String> valueFuture = function.callAsync(FunctionMode.READ, "myfun",
FunctionResult.STRING, Collections.emptyList(), "test");
RedissonReactiveClient redisson = redissonClient.reactive();
RFunctionReactive function = redisson.getFunction();
Mono<Void> load = function.load("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
Mono<String> value = function.call(FunctionMode.READ, "myfun",
FunctionResult.STRING, Collections.emptyList(), "test");
RedissonRxClient redisson = redissonClient.rxJava();
RFunctionRx function = redisson.getFunction();
Completable load = function.load("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
Maybe<String> value = function.call(FunctionMode.READ, "myfun",
FunctionResult.STRING, Collections.emptyList(), "test");
Managing libraries¶
RFunction also manages the libraries themselves: loadAndReplace overwrites an existing library, list returns the registered libraries as FunctionLibrary objects, delete removes a single library, and flush removes them all. In addition, dump and restore serialize and reload the full function state, stats reports the running engine, and kill stops a function that is stuck.
RFunction function = redisson.getFunction();
// overwrite an existing library
function.loadAndReplace("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
// inspect registered libraries
List<FunctionLibrary> libraries = function.list();
// remove a single library, or all of them
function.delete("mylib");
function.flush();
RFunction function = redisson.getFunction();
RFuture<Void> replaceFuture = function.loadAndReplaceAsync("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
RFuture<List<FunctionLibrary>> librariesFuture = function.listAsync();
RFuture<Void> deleteFuture = function.deleteAsync("mylib");
RFuture<Void> flushFuture = function.flushAsync();
RedissonReactiveClient redisson = redissonClient.reactive();
RFunctionReactive function = redisson.getFunction();
Mono<Void> replace = function.loadAndReplace("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
Mono<List<FunctionLibrary>> libraries = function.list();
Mono<Void> delete = function.delete("mylib");
Mono<Void> flush = function.flush();
RedissonRxClient redisson = redissonClient.rxJava();
RFunctionRx function = redisson.getFunction();
Completable replace = function.loadAndReplace("mylib",
"redis.register_function('myfun', function(keys, args) return args[1] end)");
Single<List<FunctionLibrary>> libraries = function.list();
Completable delete = function.delete("mylib");
Completable flush = function.flush();