gitaly: Don't block on preloading licensedb
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