2

Hack has the <<__Memoize>> attribute to easily cache method results.

How can I use it to cache results of some database or API request for a limited amount of time?

Let's say my code very frequently needs some information from a database:

public function loadEmployees(
  string $company_name,
): ImmSet<string> {
  return $this->db->sqlQuery(...);
}

To improve performance, I'd like to cache the results for one minute.

If the data changes my program should see it within a minute. I'm fine with the results being stale for one minute.

Checked the official docs.

Martin Konicek
  • 39,126
  • 20
  • 90
  • 98

2 Answers2

3

Memoize only lives in the context of a request. Your request takes more than one minute? If that is the case, Memoize is not for your use case.

Gareve
  • 3,372
  • 2
  • 21
  • 23
  • 1
    Then Memoize is perfect, thanks! I assumed it caches for the whole lifetime of the VM. This could use lots of memory but the docs say the cache can be automatically cleared if needed. – Martin Konicek Jul 06 '16 at 15:45
  • The docs now say "The __Memoize attribute allows functions or methods to cache their results for the duration of a given request." – David Phillips Feb 24 '17 at 20:17
3

<<__Memoize>> Only caches for the lifetime of the request and is not shared across requests. It's highly unlikely you have an HTTP request that lasts for more than a minute, so it sounds like you want a cache that is shared across multiple requests. APC is generally used for that (see http://php.net/apc). If you really want a more granular control of caching within a request you will need to roll your own using a static member or a global variable.

  • Then Memoize is perfect, thanks! I assumed it caches for the whole lifetime of the VM. This could use lots of memory but the docs say the cache can be automatically cleared if needed. – Martin Konicek Jul 06 '16 at 15:45
  • I'll accept @Gareve's answer as he was first, although this answer is more complete. Thank you! – Martin Konicek Jul 06 '16 at 15:46
  • 1
    Also keep in mind that there's no eviction policy for `__Memoize` -- it's cleared at the end of the request, but there's no control over how long it's held within a request; within a single request, HHVM is free to cache it forever or for some other indeterminate amount of time. There's no manual control over this at all. The idea is that it caches expensive but idempotent computations; an HTTP request will technically work but doesn't really fall into this paradigm and so if you need more complicated semantics you are better off with something else. – Josh Watzman Jul 06 '16 at 15:56