我想通过在 python 中使用 redis lua 脚本来减少我的存储,我的代码如下:
def lua_storage():
conn = redis_conn()
lua = """
local storage = redis.call('get','storage')
if (storage ~= nil) then
if tonumber(storage) >= 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
上面的代码很简单,就是一个控制good存储的lua脚本,如果good没有存储,脚本会把stroage设置为10,当用户访问这个脚本时,storage会减1直到为 0。当存储为 0 时,用户将收到“现在存储为零,可以回复 decr 操作”消息。
当我在 python 中运行此方法时,出现以下异常:
Traceback (most recent call last):
File "D:/mytools/luaredis/mytest.py", line 53, in <module>
lua_storage()
File "D:/mytools/luaredis/mytest.py", line 47, in lua_storage
result = conn.eval(lua,0)
File "C:\Python27\lib\site-packages\redis\client.py", line 2067, in eval
return self.execute_command('EVAL', script, numkeys, *keys_and_args)
File "C:\Python27\lib\site-packages\redis\client.py", line 668, in execute_command
return self.parse_response(connection, command_name, **options)
File "C:\Python27\lib\site-packages\redis\client.py", line 680, in parse_response
response = connection.read_response()
File "C:\Python27\lib\site-packages\redis\connection.py", line 629, in read_response
raise response
redis.exceptions.ResponseError: Error running script (call to f_19dc8de385a024db32cb227ec869e8b644ebbc36): @user_script:4: user_script:4: attempt to compare number with nil
我试图找出问题所在,但找不到。 对于上面的代码本身,我不认为其中有什么错误(我按照this answer写了我的代码)。我唯一想确定的是,redis 和 lua 的返回类型是否不同导致了这个异常?
我应该遵循什么好的调试方法来调试这个脚本?
----编辑----
感谢我的同事 Carol,我更改了下面的代码并得到了正确的结果:
def lua_storage():
conn = redis_conn()
lua = """
if redis.call('get','storage') then
if tonumber(redis.call('get','storage')) > 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
这里还有一个问题,我们舍弃了local storage变量,直接使用了redis.call('get','storage')。 所以我不知道为什么本地存储不能做这些事情。需要更多的工作。
感谢 Kevin,终于可以运行下面的代码了:
def lua_storage():
conn = redis_conn()
lua = """
local storage = redis.call('get','storage')
if storage ~= false then
if tonumber(storage) > 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
return redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
因为一开始存储的是nil,但是把nil放到if语句中,会返回false,所以需要把nil改成false。
最佳答案
根据Redis Lua documentation , 一个 nil Redis 值变为 false Lua值:
Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type
因此,您应该比较 GET 的结果至 false , 不是 nil .您看到此特定消息是因为 tonumber(false)是nil ,然后将其与数字 0 进行比较.
关于lua - 由于错误的类型比较,redis lua 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48087764/
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串