@@ -218,33 +218,48 @@ func (s *Store) List(_ context.Context) ([]Credential, error) {
218
218
}
219
219
220
220
func (s * Store ) RecreateAll (_ context.Context ) error {
221
- s .recreateAllLock .Lock ()
222
- defer s .recreateAllLock .Unlock ()
223
-
224
221
store , err := s .getStore ()
225
222
if err != nil {
226
223
return err
227
224
}
228
225
226
+ // We repeatedly lock and unlock the mutex in this function to give other threads a chance to talk to the credential store.
227
+ // It can take several minutes to recreate the credentials if there are hundreds of them, and we don't want to
228
+ // block all other threads while we do that.
229
+ // New credentials might be created after our GetAll, but they will be created with the current encryption configuration,
230
+ // so it's okay that they are skipped by this function.
231
+
232
+ s .recreateAllLock .Lock ()
229
233
all , err := store .GetAll ()
234
+ s .recreateAllLock .Unlock ()
230
235
if err != nil {
231
236
return err
232
237
}
233
238
234
239
// Loop through and recreate each individual credential.
235
240
for serverAddress := range all {
241
+ s .recreateAllLock .Lock ()
236
242
authConfig , err := store .Get (serverAddress )
237
243
if err != nil {
244
+ s .recreateAllLock .Unlock ()
245
+
246
+ if IsCredentialsNotFoundError (err ) {
247
+ // This can happen if the credential was deleted between the GetAll and the Get by another thread.
248
+ continue
249
+ }
238
250
return err
239
251
}
240
252
241
253
if err := store .Erase (serverAddress ); err != nil {
254
+ s .recreateAllLock .Unlock ()
242
255
return err
243
256
}
244
257
245
258
if err := store .Store (authConfig ); err != nil {
259
+ s .recreateAllLock .Unlock ()
246
260
return err
247
261
}
262
+ s .recreateAllLock .Unlock ()
248
263
}
249
264
250
265
return nil
0 commit comments