From e99a0de48971c3a062ec787e0ad895b9267c4b47 Mon Sep 17 00:00:00 2001 From: ioito Date: Tue, 19 Apr 2022 16:46:35 +0800 Subject: [PATCH] fix(region): account sync --- pkg/compute/models/cloudaccounts.go | 18 +++++++++++------- pkg/compute/tasks/cloud_account_sync_task.go | 8 ++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 3e49d201d9..2db22b27c8 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -665,7 +665,7 @@ func (self *SCloudaccount) PerformSync(ctx context.Context, userCred mcclient.To if self.CanSync() || syncRange.Force { return nil, self.StartSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "") } - return nil, nil + return nil, httperrors.NewInvalidStatusError("Unable to synchronize frequently") } // 测试账号连通性(更新秘钥信息时) @@ -847,14 +847,21 @@ func (self *SCloudaccount) StartSyncCloudProviderInfoTask(ctx context.Context, u params.Add(jsonutils.Marshal(syncRange), "sync_range") } + cloudaccountPendingSyncsMutex.Lock() + defer cloudaccountPendingSyncsMutex.Unlock() + + // 提前判断是否云账号已经在后台进行同步 + if _, ok := cloudaccountPendingSyncs[self.Id]; ok { + return errors.Wrap(httperrors.ErrConflict, "account alread in syncing") + } + task, err := taskman.TaskManager.NewTask(ctx, "CloudAccountSyncInfoTask", self, userCred, params, "", "", nil) if err != nil { return errors.Wrapf(err, "NewTask") } self.markStartSync(userCred, syncRange) db.OpsLog.LogEvent(self, db.ACT_SYNC_HOST_START, "", userCred) - task.ScheduleRun(nil) - return nil + return task.ScheduleRun(nil) } func (self *SCloudaccount) markStartSync(userCred mcclient.TokenCredential, syncRange *SSyncRange) error { @@ -2236,9 +2243,7 @@ func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCre if _, ok := cloudaccountPendingSyncs[account.Id]; ok { if waitChan != nil { go func() { - // an active cloudaccount sync task is running, return with conflict error - log.Errorf("an active cloudaccount sync task is running, early return with conflict error") - waitChan <- errors.Wrap(httperrors.ErrConflict, "cloudaccountPendingSyncs") + waitChan <- errors.Wrap(httperrors.ErrConflict, "an active cloudaccount sync task is running, early return with conflict error") }() } return @@ -2421,7 +2426,6 @@ func (account *SCloudaccount) PerformPublic(ctx context.Context, userCred mcclie }, } account.StartSyncCloudProviderInfoTask(ctx, userCred, syncRange, "") - return nil, nil } diff --git a/pkg/compute/tasks/cloud_account_sync_task.go b/pkg/compute/tasks/cloud_account_sync_task.go index 94575162c7..0760197312 100644 --- a/pkg/compute/tasks/cloud_account_sync_task.go +++ b/pkg/compute/tasks/cloud_account_sync_task.go @@ -47,12 +47,12 @@ func (self *CloudAccountSyncInfoTask) OnInit(ctx context.Context, obj db.IStanda taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) { // do sync err := cloudaccount.SyncCallSyncAccountTask(ctx, self.UserCred) - if err != nil { - if errors.Cause(err) != httperrors.ErrConflict { - log.Debugf("no other sync task, mark end sync for all cloudproviders") - cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred) + if errors.Cause(err) == httperrors.ErrConflict { + log.Errorf("account %s(%s) alread in syncing", cloudaccount.Name, cloudaccount.Provider) } + // 进入同步任务前已经mark sync, 这里需要清理下状态 + cloudaccount.MarkEndSyncWithLock(ctx, self.UserCred) return nil, errors.Wrap(err, "SyncCallSyncAccountTask") } return nil, nil