mesh-catalog's 140 module directories are 420 forge reads per merge, past the 30 s bound of a handled event while the forge is busy: the merged message of #535 timed out on every try, and #3fb7951 needed seven (issue 1458 met the same kind at 131). A tree hash names its bytes, so what was read at a tree is kept in the new state inputs and in memory, and a merge reads only the directories it changed.
58 lines
2.3 KiB
Go
58 lines
2.3 KiB
Go
package bridge
|
|
|
|
// A merge of a repository of many modules read three files of the forge for every module, whatever the merge changed:
|
|
// the catalogue's 140 modules are 420 reads, which no longer fit the 30 s bound of a handled event while the forge is
|
|
// busy after a merge, so the merged message of mesh-catalog#535 was never written and the indexer never saw it (issue
|
|
// 1126; issue 1458 met the same kind at 131 modules and raised the reads in flight). A directory's git tree hash names
|
|
// every byte under it, so the manifest and the lock-file hashes read once at a tree hash are those of every later commit
|
|
// whose directory has the same tree: a merge reads the forge only for the directories it changed.
|
|
|
|
// Inputs is what the bridge read of one module directory at one tree hash: its manifest and its lock files' hex sha256
|
|
// by name (none when it has none).
|
|
type Inputs struct {
|
|
Manifest string `json:"manifest"`
|
|
Locks map[string]string `json:"locks,omitempty"`
|
|
}
|
|
|
|
// Kept holds Inputs by a directory's git tree hash (the bridge's state bucket inputs). Get answers false for a tree it
|
|
// does not hold or cannot read; Put is best effort: a value it could not keep is read from the forge next time.
|
|
type Kept interface {
|
|
Get(tree string) (Inputs, bool)
|
|
Put(tree string, in Inputs)
|
|
}
|
|
|
|
// keptInputs splits dirs into the inputs kept for their tree hash and the directories still to read from the forge.
|
|
func keptInputs(dirs []string, trees map[string]string, kept Kept) (manifests map[string]string, locks map[string]map[string]string, read []string) {
|
|
manifests, locks = map[string]string{}, map[string]map[string]string{}
|
|
for _, dir := range dirs {
|
|
tree := trees[dir]
|
|
if kept == nil || tree == "" {
|
|
read = append(read, dir)
|
|
continue
|
|
}
|
|
in, ok := kept.Get(tree)
|
|
if !ok {
|
|
read = append(read, dir)
|
|
continue
|
|
}
|
|
manifests[dir] = in.Manifest
|
|
if len(in.Locks) > 0 {
|
|
locks[dir] = in.Locks
|
|
}
|
|
}
|
|
return manifests, locks, read
|
|
}
|
|
|
|
// keep puts what was read of each directory under its tree hash.
|
|
func keep(dirs []string, trees map[string]string, manifests map[string]string, locks map[string]map[string]string, kept Kept) {
|
|
if kept == nil {
|
|
return
|
|
}
|
|
for _, dir := range dirs {
|
|
raw, ok := manifests[dir]
|
|
if tree := trees[dir]; ok && tree != "" {
|
|
kept.Put(tree, Inputs{Manifest: raw, Locks: locks[dir]})
|
|
}
|
|
}
|
|
}
|