ARTICLE AD BOX
I'm trying to implement a document locking mechanism using Redis SET with Lua script for atomicity. I want to store a list of UUIDs as strings in a Redis SET, check which ones already exist, if any is found return the found ones, or none, than add to the cache.
However, my Lua script keeps failing with this error:
ERR Lua redis lib command arguments must be strings or integers private static final String LUA_LOCK_DOCUMENTS_SCRIPT = """ local setKey = KEYS[1] local conflictingDocs = {} for i = 2, #ARGV do local docId = ARGV[i] local existing = redis.call('SISMEMBER', setKey, docId) if existing == 1 then table.insert(conflictingDocs, docId) end end if #conflictingDocs > 0 then return conflictingDocs end local ttl = tonumber(ARGV[1]) for i = 2, #ARGV do redis.call('SADD', setKey, ARGV[i]) end redis.call('EXPIRE', setKey, ttl) return nil """; private static final String LUA_RELEASE_DOCUMENTS_SCRIPT = """ local setKey = KEYS[1] for i = 1, #ARGV do redis.call('SREM', setKey, ARGV[i]) end return 1 """; public List<String> getDocumentsVersionIdsLocked(List<String> documentVersionIds) { if (documentVersionIds == null || documentVersionIds.isEmpty()) { return Collections.emptyList(); } try { var tenant = ServiceContext.get().getCurrentTenant(); if (redissonClient == null || redissonClient.get() == null) { LOGGER.warn("RedissonClient is not available, cannot lock documents."); return Collections.emptyList(); } List<Object> key = List.of(SIGN_DOC_LOCK_SET); List<String> docIds = documentVersionIds.stream() .map(docId -> tenant + "-" + docId) .toList(); Object[] args = new Object[docIds.size() + 1]; args[0] = String.valueOf(TTL_SECONDS); // TTL como String! for (int i = 0; i < docIds.size(); i++) { args[i + 1] = docIds.get(i); } RScript script = redissonClient.get().getScript(); List<String> result = script.eval(RScript.Mode.READ_WRITE, LUA_LOCK_DOCUMENTS_SCRIPT, RScript.ReturnType.MULTI, key, args); if (result == null) { return Collections.emptyList(); } return result; } catch (Exception e) { LOGGER.warn("Error executing Lua script to lock documents. No documents will be locked.", e); return Collections.emptyList(); } }What I've tried:
Converting everything explicitly to strings with tostring() in Lua
Using redis.call('SISMEMBER', setKey, tostring(docId))
Using ARGV[i] directly without conversion
Making sure TTL is passed as a number string
The actual values being passed are definitely strings (UUIDs like "tenant-123e4567-e89b-12d3-a456-426614174000").
Question: Why is Redis claiming my arguments aren't strings or integers when they clearly are? Is Redisson wrapping the ARGV values in some non-string object (like Netty's PooledUnsafeDirectByteBuf) that Lua doesn't recognize? How do I properly extract the raw string value from whatever Redisson is passing?
