不僅可用於刪除操作,也可用於單次操作失敗需要持久進行某操作的情況。
有的時候用戶點擊刪除由於某些原因導致沒有刪除掉,或者有的資源刪除pending可能還留在頁面(如rancher上偶爾會出現該情況,刪應用,刪項目等等),一般情況下我們都是調一次刪除接口,結果分兩種,一種是成功刪除,另一種是因某報錯未刪除資源,爲後者時資源仍會留在界面上,用戶只能繼續多次進行刪除操作。這時候這個邏輯就大顯神威了,這就可以保證給用戶看到的該資源一直是removing狀態,即時第一次沒刪除,那麼該協程將繼續循環執行刪除操作,不需要用戶再去手動刪除。
以下代碼模型是看rancher源碼時發現的,刪除Templates的代碼。
代碼如下
func (m *Manager) deleteTemplates(key string, namespace string) error {
templates, err := m.getTemplateMap(key, namespace)
if err != nil {
return err
}
tvToDelete := map[string]struct{}{}
for _, t := range templates {
tvs, err := m.getTemplateVersion(t.Name, namespace)
if err != nil {
return err
}
for k := range tvs {
tvToDelete[k] = struct{}{}
}
}
// 重點是下面
go func() {
for {
// 刪除templates
for k := range templates {
if err := m.templateClient.DeleteNamespaced(namespace, k, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) {
logrus.Warnf("Deleting template %v doesn't succeed. Continue loop", k)
continue
}
}
// 刪除templateVersion
for k := range tvToDelete {
if err := m.templateVersionClient.DeleteNamespaced(namespace, k, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) {
logrus.Warnf("Deleting templateVersion %v doesn't succeed. Continue loop", k)
continue
}
}
break
}
}()
return nil
}