openSUSE:WebYaST 缓存
WebYaST 缓存
工作原理
最近的发布版本表明,WebYaST 的后端速度太慢。特别是启动新的模块通常需要花费太多时间。
系统管理工具基于很少更改的数据(例如用户、打印机、网络设置),但评估这些数据需要消耗大量时间。因此,想法是在启动 WebYaST 时将这些数据预加载到缓存中,以便立即使用。
如果 UI 使用了缓存,将并行启动一个任务以再次从系统评估这些数据。如果新评估的数据与缓存不同,UI/用户将被告知,并且 UI 将重新加载
| WebYaST | http 通信 | HTTP 浏览器 |
|---|---|---|
| * 使用以下命令启动:rcwebyast start | ||
| * 遍历所有模型,调用 find 方法, 并将结果插入缓存 User.find(:all) Network.find(:all) Ldap.find(:all) ... .. . |
||
| * 显示例如 用户索引页面 | ||
| <--- GET User/ --- | * 从 WebYaST 获取所有用户 | |
| * 读取 User.find(:all) 的缓存 | --- User.find(:all) ---> | * 在 UI 中显示所有用户 |
| * 调用 User.find(:all) 以检查和更新缓存。 | ||
| <--- GET notifier/user --- | * 轮询缓存是否在此期间已更改。 | |
| * 检查用户缓存是否已更改 ? | --- 是/否 --> | * 如果数据在此期间已更改,则更新 UI |
| * 定期轮询更改的缓存 ... .. . |
一个不错的“副作用”是,如果后台在此期间更改了一些数据,其他 UI 也会收到通知。例如,两个用户同时编辑网络配置。在一位用户保存了他的值后,第二位用户将被告知数据已更改,并且他将获得更新。
如何实现
如果要在插件中使用此缓存机制,则需要更改模型类中的以下方法。以下是 Group 模型类(文件:plugins/users/app/models/group.rb)的示例
require 'yast_service'
包含所需的库。
def self.find (cn)
return find_all if cn == :all
YastCache.fetch(self, cn) {
result = group_get( "system", cn )
result = group_get( "local", cn ) if result.empty?
return nil if result.empty?
make_group result
}
end
def self.find_all
YastCache.fetch(self, :all) {
result = groups_get "local"
result.update( groups_get "system")
result_array = []
result.each { |k,v| result_array << make_group(v) }
result_array.sort! {|x,y| x.cn <=> y.cn}
}
YastCache.fetch(self, cn) 和 YastCache.fetch(self, :all) 使用 ID cn 或 :all 读取 groups 缓存。如果为空,将执行给定的代码块,并将评估值插入缓存并返回。
def save
existing_group = Group.group_get( group_type, old_cn )
if existing_group.empty?
result = YastService.Call( "YaPI::USERS::GroupAdd",
{ "type" => ["s", group_type] },
{ "cn" => ["s",cn], "userlist" => ["as", members] } )
else
result = YastService.Call( "YaPI::USERS::GroupModify",
{ "type" => ["s", group_type],
"cn" => ["s", old_cn] },
{ "gidNumber" => ["i", gid],
"cn" => ["s",cn],
"userlist" => ["as", members] }
)
end
YastCache.reset(self, old_cn)
result # result is empty string on success, error message otherwise
end
使用 YastCache.reset(self, old_cn) 使缓存无效,并在后台重新填充。
def destroy
existing_group = Group.group_get( group_type, old_cn )
if existing_group.empty?
ret = ""
else
ret = YastService.Call( "YaPI::USERS::GroupDelete", {"type" => ["s",group_type], "cn" => ["s",old_cn]})
end
YastCache.delete(self,old_cn)
ret
end
YastCache.delete(self,old_cn) 删除该组的缓存。