Сохранить локальный промежуточный результат 'rpop' в скрипте redis lua - PullRequest
0 голосов
/ 05 августа 2020
        # Check processing queue for any previously unprocessed items.
        # If previously unprocessed item
        # Check if item key is not expired and push back to processing queue
        # Otherwise push back onto work queue
        # (May want to r_push if we need immediate processing)
        lua_script = f"""
            local saved_item = redis.call('rpop', 'processing_list')

            if (saved_item ~= nil) then
                if (redis.call('exists', 'processing_list' .. _ .. saved_item) == 1) then
                    redis.call('lpush', 'processing_list', saved_item)
                else
                    redis.call('lpush', 'work_list', saved_item)
                end
            end
        """
        self._queue_client.get_redis_client().eval(lua_script, 0)

Выше я пытаюсь реализовать стойкую очередь с помощью redis. Мне нужно, чтобы эта часть logi c была atomi c, но, поскольку транзакции redis не допускают промежуточных операций чтения и записи, мне пришлось прибегнуть к lua. Проблема в том, что начальная строка «rpop» не работает. Я проверил в своем redis-cli, что он возвращает (nil) и, следовательно, переменная «saved_item» никогда не устанавливается правильно. Есть ли лучший подход для выполнения sh этого промежуточного чтения, а затем условного logi c с использованием этого значения?

1 Ответ

0 голосов
/ 07 августа 2020

Как новичок в lua, мне пришлось взламывать это, пока оно не сработало, и до сих пор не понял, почему, не прочесывая lua документы. Ключ состоял в том, чтобы создать локальную функцию для возврата элемента rpop из него и сохранения его в локальной переменной, а не пытаться напрямую. Что-то, связанное с возвращаемыми значениями Lua.

        lua_script = f"""
        if (redis.call('exists', '{self._processing_queue_name}') == 1) then
            local rpop = function (list) return redis.call('rpop', list) end
            local saved_item = rpop('{self._processing_queue_name}')

            if (saved_item ~= nil) then
                if (redis.call('exists', '{self._processing_queue_name}' .. '_' .. saved_item) == 1) then
                    redis.call('lpush', '{self._processing_queue_name}', saved_item)
                else
                    redis.call('lpush', '{self._queue_name}', saved_item)
                end
            end
        end
    """
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...