internal/pkg: cache extern responses
Test / Create distribution (push) Successful in 58s
Test / Sandbox (push) Successful in 2m24s
Test / ShareFS (push) Successful in 3m27s
Test / Hakurei (push) Successful in 3m46s
Test / Sandbox (race detector) (push) Successful in 5m1s
Test / Hakurei (race detector) (push) Successful in 6m15s
Test / Flake checks (push) Successful in 1m19s
Test / Create distribution (push) Successful in 58s
Test / Sandbox (push) Successful in 2m24s
Test / ShareFS (push) Successful in 3m27s
Test / Hakurei (push) Successful in 3m46s
Test / Sandbox (race detector) (push) Successful in 5m1s
Test / Hakurei (race detector) (push) Successful in 6m15s
Test / Flake checks (push) Successful in 1m19s
This prepares substitute computation for shallow extern replacements. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
+34
-23
@@ -770,6 +770,8 @@ type Cache struct {
|
||||
|
||||
// Optional external cache implementation.
|
||||
extern External
|
||||
// Caches responses from extern.
|
||||
externCache map[unique.Handle[ID]]unique.Handle[Checksum]
|
||||
// Synchronises access to extern.
|
||||
externMu sync.RWMutex
|
||||
|
||||
@@ -930,6 +932,7 @@ func readlinkChecksum(a *check.Absolute, buf *Checksum) error {
|
||||
// SetExternal sets e as the [External] implementation of c.
|
||||
func (c *Cache) SetExternal(e External) {
|
||||
c.externMu.Lock()
|
||||
c.externCache = make(map[unique.Handle[ID]]unique.Handle[Checksum])
|
||||
c.extern = e
|
||||
c.externMu.Unlock()
|
||||
}
|
||||
@@ -1849,37 +1852,45 @@ func (r *RContext) NewMeasuredReader(
|
||||
}
|
||||
|
||||
// tryExtern attempts to obtain an [Artifact] outcome from extern.
|
||||
func (c *Cache) tryExtern(ctx context.Context, id unique.Handle[ID]) (
|
||||
func (c *Cache) tryExtern(
|
||||
ctx context.Context,
|
||||
id unique.Handle[ID],
|
||||
status *io.ReadCloser,
|
||||
) (
|
||||
unique.Handle[Checksum],
|
||||
io.ReadCloser,
|
||||
error,
|
||||
) {
|
||||
c.externMu.RLock()
|
||||
defer c.externMu.RUnlock()
|
||||
|
||||
if c.extern == nil {
|
||||
return zeroChecksum, nil, nil
|
||||
checksum, ok := c.externCache[id]
|
||||
if !ok {
|
||||
if c.extern == nil {
|
||||
return zeroChecksum, nil
|
||||
}
|
||||
|
||||
v, err := c.extern.Artifact(ctx, id)
|
||||
if err != nil {
|
||||
return zeroChecksum, err
|
||||
}
|
||||
if v == nil {
|
||||
return zeroChecksum, nil
|
||||
}
|
||||
checksum = unique.Make(*v)
|
||||
|
||||
var got unique.Handle[Checksum]
|
||||
if _, got, err = c.Cure(c.extern.Checksum(checksum)); err != nil {
|
||||
return checksum, err
|
||||
} else if got != checksum {
|
||||
return zeroChecksum, &ChecksumMismatchError{got.Value(), checksum.Value()}
|
||||
}
|
||||
}
|
||||
|
||||
v, err := c.extern.Artifact(ctx, id)
|
||||
if err != nil {
|
||||
return zeroChecksum, nil, err
|
||||
var err error
|
||||
if status != nil {
|
||||
*status, err = c.extern.Status(&RContext{common{ctx, c}}, id)
|
||||
}
|
||||
if v == nil {
|
||||
return zeroChecksum, nil, nil
|
||||
}
|
||||
checksum := unique.Make(*v)
|
||||
|
||||
var got unique.Handle[Checksum]
|
||||
if _, got, err = c.Cure(c.extern.Checksum(checksum)); err != nil {
|
||||
return checksum, nil, err
|
||||
} else if got != checksum {
|
||||
return zeroChecksum, nil, &ChecksumMismatchError{got.Value(), checksum.Value()}
|
||||
}
|
||||
|
||||
var status io.ReadCloser
|
||||
status, err = c.extern.Status(&RContext{common{ctx, c}}, id)
|
||||
return checksum, status, err
|
||||
return checksum, err
|
||||
}
|
||||
|
||||
// cure implements Cure without acquiring a read lock on abortMu. cure must not
|
||||
@@ -2225,7 +2236,7 @@ func (c *Cache) cure(a Artifact, curesExempt bool) (
|
||||
externChecksum unique.Handle[Checksum]
|
||||
externStatus io.ReadCloser
|
||||
)
|
||||
if externChecksum, externStatus, err = c.tryExtern(ctx, id); err != nil {
|
||||
if externChecksum, err = c.tryExtern(ctx, id, &externStatus); err != nil {
|
||||
if c.msg.IsVerbose() {
|
||||
c.msg.Verbosef("extern %s: %v", reportName(ca, id), err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user