Cache of repository objects
Like hgwebdir
, HGitaly creates a new localrepo
object in RAM for each request. This is perhaps acceptable for HTTP serving, because of the so-many persistent caches that Mercurial sports, but the rate of requests that the Rails application produces is much higher than the typical interaction with a Mercurial HTTP client, making the overhead more problematic.
Also, repeated creation and destruction of repository objects makes any related memory leak that would be anecdotical for CLI Mercurial usage a major issue. This is arguably what happened with the leak fixed for heptapod#466 (closed).
Therefore, a simple LRU cache system would be advisable. We'd only need an identifier for the latest transaction to perform the necessary invalidations. That identifier could in turn itself be systematically set by py-heptapod hooks, as it's already a basic assumption that all write operations must go through them.
Currently, HGitaly is mostly read-only. I think I'd prefer to implement the cache right now (handling the few existing writes correctly) rather than after the introduction of the write-focused gRPC methods of the %HGitaly3: fully in charge milestone. Basically we'll need to detect a change in latest transaction after acquisition of the locks and perform the corresponding invalidations if needed. It's obviously best to do it upfront, but there may be cases where it's not possible.
Persistent caches could become a concern, even in read-only cases, as it will be much harder to detect an update in them to invalidate their RAM counterparts. Updates in caches that haven't been triggered by actual writes should be matters of optimization, though.