Как определить функции в redis \ lua?

Я использую Node.js и модуль 'redis-scripto', и я пытаюсь определить функцию в Lua:

 var redis = require("redis");  
 var redisClient = redis.createClient("6379","127.0.0.1");   

 var Scripto = require('redis-scripto');
 var scriptManager = new Scripto(redisClient);
 var scripts = {'add_script':'function add(i,j) return (i+j) end add(i,j)'};

 scriptManager.load(scripts);
 scriptManager.run('add_script', [], [1,1], function(err, result){
                    console.log(err || result);
 });

поэтому я получаю эту ошибку:

[Ошибка: ERR Ошибка запуска сценария (вызов.... @enable_strict_lua:7: user_script:1: Сценарий попытался создать глобальную переменную 'add']

поэтому я обнаружил, что это защита, как объясняется в этой теме:

"Строка документа scriptingEnableGlobalsProtection указывает на то, что цель состоит в том, чтобы уведомить авторов сценариев об общей ошибке (не используя local)".

но я так и не понял - где этот scripting.c? и решение изменения глобальных таблиц мне кажется рискованным.

Нет ли простого способа установки функций для redis - используя lua?

3 ответа

Решение

Это сработало для меня: (измените строку 5 с вопроса выше):

var scripts = {
'add_script':'local function add(i,j) return (i+j) end return(add(ARGV[1],ARGV[2]))'};

чтобы передать переменные в скрипт, используйте KEYS[] и ARGV[], как объяснено в руководстве по redis-scripto, а также здесь есть хороший пример: " Lua: Руководство для пользователей Redis"

Похоже, что скрипт запускает ваш код в функции. Поэтому, когда вы создаете function add(), он думает, что вы делаете это внутри функции случайно. Также, вероятно, возникнет аналогичная проблема с аргументами вызова add(i,j), Если это правильно, то это должно работать:

local function add(i,j) return (i+j) end return add(1,1)

и если это сработает, то, надеюсь, так будет и с вашими аргументами, переданными из js:

local function add(i,j) return (i+j) end return add(...)

Вы должны назначить анонимную функцию переменной (используя локальную).

local just_return_it = function(value) 
    return value
end 

--// result contains the string "hello world"
local result = just_return_it("hello world")

Кроме того, вы можете создать таблицу и добавить функции в виде полей в таблице. Это позволяет более объектно-ориентированный стиль.

local obj = {}

function obj.name()
    return "my name is Tom"
end

--// result contains "my name is Tom" 
local result = obj.name()

Redis требует этого, чтобы предотвратить доступ к глобальной области. Весь механизм сценариев разработан так, чтобы не допускать постоянства на уровне сценариев. Разрешение вещей в глобальном масштабе создаст простой способ подорвать это, значительно усложняя отслеживание и управление состоянием на сервере.

Примечание: это означает, что вам придется добавлять одинаковые функции в каждый скрипт, который их использует. Они не постоянны на сервере.

Другие вопросы по тегам