Skip to content

Commit b28f9ee

Browse files
committed
proof: re-try in HasProofs if some are unavailable
When CPU cycles are constrained (e.g. in CI), it can sometimes happen that we: - Import a proof into the multi archiver - The multi archiver imports it into each backend - The first backend notifies its subscribers after importing - The custodian reacts to the notification and checks HasProof on the multi archiver - Because the other goroutine hasn't finished importing into all backends, HasProof returns false - The custodian only finishes the transfer once it receives the notification from the second backend All the above leads to the situation where the status "proof received" is fired twice instead of just once, which causes the itests to fail sometimes.
1 parent e5af40e commit b28f9ee

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

proof/archive.go

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -879,21 +879,54 @@ func (m *MultiArchiver) FetchIssuanceProof(ctx context.Context,
879879
// intended to be a performance optimized lookup compared to fetching a proof
880880
// and checking for ErrProofNotFound. The multi archiver only considers a proof
881881
// to be present if all backends have it.
882-
func (m *MultiArchiver) HasProof(ctx context.Context, id Locator) (bool, error) {
882+
func (m *MultiArchiver) HasProof(ctx context.Context,
883+
id Locator) (bool, error) {
884+
885+
var (
886+
someHaveProof = false
887+
allHaveProof = true
888+
)
883889
for _, archive := range m.backends {
884890
ok, err := archive.HasProof(ctx, id)
885891
if err != nil {
886892
return false, err
887893
}
888894

889-
// We are expecting all backends to have the proof, otherwise we
890-
// consider the proof not to be found.
891-
if !ok {
892-
return false, nil
893-
}
895+
someHaveProof = someHaveProof || ok
896+
allHaveProof = allHaveProof && ok
897+
}
898+
899+
// If all backends have the proof, then we don't need to do anything
900+
// further and can return that result.
901+
if allHaveProof {
902+
return true, nil
894903
}
895904

896-
return true, nil
905+
// If no backends have the proof, then this is just a proof we don't
906+
// know about, which is fine too.
907+
if !someHaveProof {
908+
return false, nil
909+
}
910+
911+
// If only some but not all backends have the proof, it's possible that
912+
// the other ones are in the process of importing it right now. So we
913+
// re-try a couple of times to see if the proof becomes available
914+
// eventually.
915+
return fn.RetryFuncN(
916+
ctx, fn.DefaultRetryConfig(), func() (bool, error) {
917+
allHaveProof = true
918+
for _, archive := range m.backends {
919+
ok, err := archive.HasProof(ctx, id)
920+
if err != nil {
921+
return false, err
922+
}
923+
924+
allHaveProof = allHaveProof && ok
925+
}
926+
927+
return allHaveProof, nil
928+
},
929+
)
897930
}
898931

899932
// FetchProofs fetches all proofs for assets uniquely identified by the passed

0 commit comments

Comments
 (0)