executeTransactionWithRetry wraps a database transaction with a retry mechanism.
(operation func(tx *gorm.DB) error)
| 114 | |
| 115 | // executeTransactionWithRetry wraps a database transaction with a retry mechanism. |
| 116 | func (p *KeyProvider) executeTransactionWithRetry(operation func(tx *gorm.DB) error) error { |
| 117 | const maxRetries = 3 |
| 118 | const baseDelay = 50 * time.Millisecond |
| 119 | const maxJitter = 150 * time.Millisecond |
| 120 | var err error |
| 121 | |
| 122 | for i := range maxRetries { |
| 123 | err = p.db.Transaction(operation) |
| 124 | if err == nil { |
| 125 | return nil |
| 126 | } |
| 127 | |
| 128 | if strings.Contains(err.Error(), "database is locked") { |
| 129 | jitter := time.Duration(rand.Intn(int(maxJitter))) |
| 130 | totalDelay := baseDelay + jitter |
| 131 | logrus.Debugf("Database is locked, retrying in %v... (attempt %d/%d)", totalDelay, i+1, maxRetries) |
| 132 | time.Sleep(totalDelay) |
| 133 | continue |
| 134 | } |
| 135 | |
| 136 | break |
| 137 | } |
| 138 | |
| 139 | return err |
| 140 | } |
| 141 | |
| 142 | func (p *KeyProvider) handleSuccess(keyID uint, keyHashKey, activeKeysListKey string) error { |
| 143 | keyDetails, err := p.store.HGetAll(keyHashKey) |
no test coverage detected