1

设置

我正在尝试实现一种相当常见的缓存模式。这就是我想要发生的事情:

  1. 第一次请求记录时,它的值被缓存。
  2. 后续请求返回缓存的记录。
  3. 更改记录时,缓存的版本将被标记为无效。
  4. 对记录的下一个请求会缓存一个新值。

问题

Cache.simple()按预期缓存值,但我似乎没有使缓存值无效的工具。Cache.make()似乎是用于这项工作的工具,但我未能成功使用它。

来源

这是一个完整的示例(构建和运行)。我想在结束时使缓存的记录无效set_name(在存储一个新值之后)。如果缓存记录成功失效,则在页面刷新时应显示从文本输入提交的名称。

type User.t = 
  { id : int 
  ; name : string
  }

db /user: intmap(User.t)

create_user() =
  match ?/user[0] with
  | {none} -> /user[0] <- {id=0 name="tom"}
  | _ -> void

set_name(new_name: string) =
  /user[0]/name <- new_name
  // After setting a new name, invalidate the cached result.

_get_name(uid:int) : string =
  /user[uid]/name
get_name = Cache.simple(_get_name)

page() =
  do create_user()
  <>User's name is "{get_name(0)}"</>

  <form onsubmit={_ -> set_name(Dom.get_value(#name_input))}>
    <input type="text" id=#name_input />
  </form>

server = one_page_server("User", page)

谢谢。

4

1 回答 1

1

Indeed Cache.make is the way to go if you want more control, i.e. in this case invalidate the results. What problem did you have?

You need to start with creating a cache over your _get_name function. For that you can mimic Cache.simple:

get_name = Cache.make(Cache.Negotiator.always_necessary(_get_name), Cache.default_options)

then instead of get_name use get_name.get (get_name is the cache) and in your create_user function use get_name.invalidate(0) to invalidate the cached result.

Does that help?

于 2011-10-24T07:03:22.240 回答