github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/storage/badger/operation/modifiers.go (about)

     1  package operation
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/dgraph-io/badger/v2"
     7  
     8  	"github.com/onflow/flow-go/module/metrics"
     9  	"github.com/onflow/flow-go/storage"
    10  	"github.com/onflow/flow-go/storage/badger/transaction"
    11  )
    12  
    13  func SkipDuplicates(op func(*badger.Txn) error) func(tx *badger.Txn) error {
    14  	return func(tx *badger.Txn) error {
    15  		err := op(tx)
    16  		if errors.Is(err, storage.ErrAlreadyExists) {
    17  			metrics.GetStorageCollector().SkipDuplicate()
    18  			return nil
    19  		}
    20  		return err
    21  	}
    22  }
    23  
    24  func SkipDuplicatesTx(op func(*transaction.Tx) error) func(tx *transaction.Tx) error {
    25  	return func(tx *transaction.Tx) error {
    26  		err := op(tx)
    27  		if errors.Is(err, storage.ErrAlreadyExists) {
    28  			metrics.GetStorageCollector().SkipDuplicate()
    29  			return nil
    30  		}
    31  		return err
    32  	}
    33  }
    34  
    35  func SkipNonExist(op func(*badger.Txn) error) func(tx *badger.Txn) error {
    36  	return func(tx *badger.Txn) error {
    37  		err := op(tx)
    38  		if errors.Is(err, badger.ErrKeyNotFound) {
    39  			return nil
    40  		}
    41  		if errors.Is(err, storage.ErrNotFound) {
    42  			return nil
    43  		}
    44  		return err
    45  	}
    46  }
    47  
    48  func RetryOnConflict(action func(func(*badger.Txn) error) error, op func(tx *badger.Txn) error) error {
    49  	for {
    50  		err := action(op)
    51  		if errors.Is(err, badger.ErrConflict) {
    52  			metrics.GetStorageCollector().RetryOnConflict()
    53  			continue
    54  		}
    55  		return err
    56  	}
    57  }
    58  
    59  func RetryOnConflictTx(db *badger.DB, action func(*badger.DB, func(*transaction.Tx) error) error, op func(*transaction.Tx) error) error {
    60  	for {
    61  		err := action(db, op)
    62  		if errors.Is(err, badger.ErrConflict) {
    63  			metrics.GetStorageCollector().RetryOnConflict()
    64  			continue
    65  		}
    66  		return err
    67  	}
    68  }