我将公交车站到达时间和路线 ID 缓存在一个 Redis 集合中,每个公交车站一组。我正在寻找一种简单的方法来更新这些集合,删除过去的到达时间,同时保留任何其他 future 的到达时间。如何在写入时根据特定条件过滤集合?
有一段时间没有写入的集会过期,所以我只关心不断更新的集,本质上是在元素级别而不是集级别设置过期。
最佳答案
以下将过滤掉小于 KEYS[2] 的值(在我的例子中是 UNIX 时间戳,因为 Redis 中的 LUA 脚本无法访问日期/时间信息而这样传递)。第二个子句然后添加传递给脚本的任何其他值。
local members_expired = 0 -- number of members expired/removed
local additions_attempted = 0 -- number of SADD attempts
local members_added = 0 -- number of members successfully added
local key = KEYS[1] -- the key of the set to update
local current_time = KEYS[2] -- the current timestamp
-- iterate through existing members and "expire" (remove) any members
-- less than the current time
for index, value in next, redis.call('SMEMBERS', key) do
-- interpret the first 10 characters of the member as a timestamp,
-- allowing us to include additional data such as the route ID
if string.sub(value, 1, 10) < current_time then
redis.call('SREM', key, value);
members_expired = members_expired + 1
end
end
-- iterate through provided members and attempt to insert them into the
-- target set
for index, value in next, ARGV do
additions_attempted = additions_attempted + 1
members_added = members_added + redis.call('SADD', key, value)
end
-- number of duplicate members
local duplicates_ignored = additions_attempted - members_added
-- entire set will expire in 1 week unless it's updated in the meantime
redis.call('EXPIRE', key, 604800)
return {
members_added,
members_expired,
duplicates_ignored
}
脚本采用以下参数:
[timestamp]:[extra_data]的一个或多个值,例如1474904925:route_123它返回一个包含以下值的数组:
PHP 示例(使用 Predis ):
$predis = new Predis\Client();
$time = time();
// some time in the future to add to the set
$values = [
($time + 3600) . ':route_123',
($time + 7200) . ':route_123',
($time + 7200) . ':route_456',
($time + 7200) . ':route_456', // this is a duplicate
];
$filter_script = <<<LUA
local members_expired = 0 -- number of members expired/removed
local additions_attempted = 0 -- number of SADD attempts
local members_added = 0 -- number of members successfully added
local key = KEYS[1] -- the key of the set to update
local current_time = KEYS[2] -- the current timestamp
-- iterate through existing members and "expire" (remove) any members
-- less than the current time
for index, value in next, redis.call('SMEMBERS', key) do
-- interpret the first 10 characters of the member as a timestamp,
-- allowing us to include additional data such as the route ID
if string.sub(value, 1, 10) < current_time then
redis.call('SREM', key, value);
members_expired = members_expired + 1
end
end
-- iterate through provided members and attempt to insert them into the
-- target set
for index, value in next, ARGV do
additions_attempted = additions_attempted + 1
members_added = members_added + redis.call('SADD', key, value)
end
-- number of duplicate members
local duplicates_ignored = additions_attempted - members_added
-- entire set will expire in 1 week unless it's updated in the meantime
redis.call('EXPIRE', key, 604800)
return {
members_added,
members_expired,
duplicates_ignored
}
LUA;
// We can run the script directly...
list($members_added, $members_expired, $duplicates_ignored) = $predis->eval(
$filter_script,
2,
'somekey',
$time,
$values[0],
$values[1],
$values[2],
$values[3]
);
echo "Members added: $members_added\n";
echo "Members expired: $members_expired\n";
echo "Duplicate members ignored: $duplicates_ignored\n";
echo "\n";
// or save it for faster execution if we're going to run repeatedly
$members_added_total = 0;
$members_expired_total = 0;
$duplicates_ignored_total = 0;
$filter_script_sha = $predis->script('LOAD', $filter_script);
foreach ($values as $value) {
list($members_added, $members_expired, $duplicates_ignored) =
$predis->evalsha($filter_script_sha, 2, 'somekey', $time, $value);
echo "[$members_added, $members_expired, $duplicates_ignored]\n";
$members_added_total += $members_added;
$members_expired_total += $members_expired;
$duplicates_ignored_total += $duplicates_ignored;
}
echo "Members added: $members_added_total\n";
echo "Members expired: $members_expired_total\n";
echo "Duplicate members ignored: $duplicates_ignored_total\n";
KEYS LUA 变量的参数数量 - 参见 docs)KEYS[1] 读取/修改的keyKEYS[2] 当前 UNIX 时间戳VALUES 要添加到集合中的任何新值关于lua - 从 Redis 集中过滤/删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35677682/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s