@@ -218,33 +218,48 @@ func (s *Store) List(_ context.Context) ([]Credential, error) {
218218}
219219
220220func (s * Store ) RecreateAll (_ context.Context ) error {
221- s .recreateAllLock .Lock ()
222- defer s .recreateAllLock .Unlock ()
223-
224221 store , err := s .getStore ()
225222 if err != nil {
226223 return err
227224 }
228225
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 ()
229233 all , err := store .GetAll ()
234+ s .recreateAllLock .Unlock ()
230235 if err != nil {
231236 return err
232237 }
233238
234239 // Loop through and recreate each individual credential.
235240 for serverAddress := range all {
241+ s .recreateAllLock .Lock ()
236242 authConfig , err := store .Get (serverAddress )
237243 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+ }
238250 return err
239251 }
240252
241253 if err := store .Erase (serverAddress ); err != nil {
254+ s .recreateAllLock .Unlock ()
242255 return err
243256 }
244257
245258 if err := store .Store (authConfig ); err != nil {
259+ s .recreateAllLock .Unlock ()
246260 return err
247261 }
262+ s .recreateAllLock .Unlock ()
248263 }
249264
250265 return nil
0 commit comments