Skip to content

gitaly: Don't block on preloading licensedb

Will Chandler (ex-GitLab) requested to merge wc/license-preload-async into master

Currently when starting a new Gitaly process, we wait for licensedb.Preload() to complete before accepting traffic. This is a heavy task that may take several seconds, but is only used by the FindLicense RPC, which on dotcom is typically called once per minute.

To allow Gitaly to start faster, move the license task to a goroutine. Internally, licensedb.Preload() is calling a sync.Once function to initialize the DB. All other functions that access the DB do the same, so there is no risk of our running a request against a partially initialized DB.

However, this may potentially cause a slow response for FindLicense requests that comes in immediately after Gitaly starts, but this will be a rare occurance. We cache repository license information on-disk, so in the common case we still won't need to wait for the DB to finish loading. On dotcom, Gitaly hosts receive these requests roughly once a minute, volume is quite low.

This change will be most useful when coming out of a cold start and in containerized environments, when no pre-existing Gitaly process can take traffic in the meantime. Benchmarking by adding os.Exit(0) at the end of run() in internal/cmd/gitaly/serve.go, we see Gitaly available to take requests ~10x faster.

Benchmark 1: ./async serve config.toml
  Time (mean ± σ):     189.3 ms ±  12.0 ms    [User: 257.7 ms, System: 73.5 ms]
  Range (min … max):   171.8 ms … 218.4 ms    15 runs

Benchmark 2: ./master serve config.toml
  Time (mean ± σ):      1.793 s ±  0.018 s    [User: 2.069 s, System: 0.094 s]
  Range (min … max):    1.768 s …  1.837 s    10 runs

Summary
  ./async serve config.toml ran 9.47 ± 0.61 times faster than ./master serve config.toml

Merge request reports