in server/datasource/etcd/kv/kv_dao.go [380:449]
func txnFindManyAndDelete(ctx context.Context, kvIDs []string, project, domain string) ([]*model.KVDoc, int64, error) {
var docs []*model.KVDoc
var opOptions []etcdadpt.OpOptions
kvTotalNum := len(kvIDs)
docs = make([]*model.KVDoc, kvTotalNum)
tasks := make([]*sync.Task, kvTotalNum)
tombstones := make([]*sync.Tombstone, kvTotalNum)
successKVNum := 0
for i := 0; i < kvTotalNum; i++ {
kvDoc, err := getKVDoc(ctx, domain, project, kvIDs[i])
// if not find the kv, continue
if err != nil {
if err == datasource.ErrKeyNotExists {
openlog.Error(err.Error())
continue
}
return nil, 0, err
}
if kvDoc == nil {
continue
}
task, err := sync.NewTask(domain, project, sync.DeleteAction, datasource.ConfigResource, kvDoc)
if err != nil {
openlog.Error("fail to create task")
return nil, 0, err
}
docs[successKVNum] = kvDoc
tasks[successKVNum] = task
tombstones[successKVNum] = sync.NewTombstone(domain, project, datasource.ConfigResource,
datasource.TombstoneID(kvDoc))
successKVNum++
}
if successKVNum == 0 {
return nil, 0, datasource.ErrKeyNotExists
}
if successKVNum != kvTotalNum {
docs = docs[:successKVNum]
tasks = tasks[:successKVNum]
tombstones = tombstones[:successKVNum]
}
for _, id := range kvIDs {
opOptions = append(opOptions, etcdadpt.OpDel(etcdadpt.WithStrKey(key.KV(domain, project, id))))
}
for _, task := range tasks {
taskBytes, err := json.Marshal(task)
if err != nil {
openlog.Error("fail to marshal task" + err.Error())
return nil, 0, err
}
opOptions = append(opOptions, etcdadpt.OpPut(etcdadpt.WithStrKey(key.TaskKey(domain, project,
task.ID, task.Timestamp)), etcdadpt.WithValue(taskBytes)))
}
for _, tombstone := range tombstones {
tombstoneBytes, err := json.Marshal(tombstone)
if err != nil {
openlog.Error("fail to marshal tombstone" + err.Error())
return nil, 0, err
}
opOptions = append(opOptions, etcdadpt.OpPut(etcdadpt.WithStrKey(key.TombstoneKey(domain, project,
tombstone.ResourceType, tombstone.ResourceID)), etcdadpt.WithValue(tombstoneBytes)))
}
err := etcdadpt.Txn(ctx, opOptions)
if err != nil {
openlog.Error("find many and delete error", openlog.WithTags(openlog.Tags{
"err": err.Error(),
}))
return nil, 0, err
}
return docs, int64(successKVNum), nil
}