Skip to content

Commit c591e52

Browse files
fix(dts): pause sync job before isolation to prevent UnsupportedOperation on delete
The Delete function called IsolateSyncJobs directly on running jobs, which Tencent rejects with UnsupportedOperation. Added a pre-isolation status check that pauses the job first if it is still running, then proceeds with isolation. Also fixed the Read function to return nil (not an error) when the job is not found, allowing Terraform to remove stale state entries gracefully instead of failing every subsequent plan. Fixes: UnsupportedOperation.UnsupportedOperationError on destroy Fixes: "resource syncJob sync-xxx does not exist" breaking plan after out-of-band deletion
1 parent a8a2245 commit c591e52

2 files changed

Lines changed: 55 additions & 2 deletions

File tree

tencentcloud/services/dts/resource_tc_dts_sync_job.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package dts
22

33
import (
44
"context"
5-
"fmt"
65
"log"
76
"time"
87

@@ -238,7 +237,7 @@ func resourceTencentCloudDtsSyncJobRead(d *schema.ResourceData, meta interface{}
238237

239238
if syncJob == nil {
240239
d.SetId("")
241-
return fmt.Errorf("resource `syncJob` %s does not exist", syncJobId)
240+
return nil
242241
}
243242

244243
if syncJob.PayMode != nil {
@@ -311,6 +310,35 @@ func resourceTencentCloudDtsSyncJobDelete(d *schema.ResourceData, meta interface
311310

312311
syncJobId := d.Id()
313312

313+
// Check current state before attempting isolation.
314+
syncJob, err := service.DescribeDtsSyncJob(ctx, helper.String(syncJobId))
315+
if err != nil {
316+
return err
317+
}
318+
319+
// Job already gone — remove from state cleanly.
320+
if syncJob == nil {
321+
return nil
322+
}
323+
324+
// Job already in a billing-terminal state (auto-deleted by Tencent) — nothing to do.
325+
if syncJob.TradeStatus != nil && (*syncJob.TradeStatus == "NotBilledByInternational" || *syncJob.TradeStatus == "NotBilled") {
326+
return nil
327+
}
328+
329+
// Job is running or syncing — pause it first so isolation is accepted.
330+
if syncJob.Status != nil && *syncJob.Status != "Paused" && *syncJob.Status != "Isolated" {
331+
log.Printf("[DEBUG]%s sync job[%s] is in status [%s], pausing before isolation\n", logId, syncJobId, *syncJob.Status)
332+
if err := service.PauseDtsSyncJobById(ctx, syncJobId); err != nil {
333+
return err
334+
}
335+
336+
conf := tccommon.BuildStateChangeConf([]string{}, []string{"Paused"}, 2*tccommon.ReadRetryTimeout, time.Second, service.DtsSyncJobStateRefreshFunc(syncJobId, "Paused", []string{}))
337+
if _, e := conf.WaitForState(); e != nil {
338+
return e
339+
}
340+
}
341+
314342
if err := service.IsolateDtsSyncJobById(ctx, syncJobId); err != nil {
315343
return err
316344
}

tencentcloud/services/dts/service_tencentcloud_dts.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,31 @@ func (me *DtsService) DescribeDtsSyncJobsByFilter(ctx context.Context, param map
136136
return
137137
}
138138

139+
func (me *DtsService) PauseDtsSyncJobById(ctx context.Context, jobId string) (errRet error) {
140+
logId := tccommon.GetLogId(ctx)
141+
142+
request := dts.NewPauseSyncJobRequest()
143+
request.JobId = helper.String(jobId)
144+
145+
defer func() {
146+
if errRet != nil {
147+
log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n",
148+
logId, "pause object", request.ToJsonString(), errRet.Error())
149+
}
150+
}()
151+
152+
ratelimit.Check(request.GetAction())
153+
response, err := me.client.UseDtsClient().PauseSyncJob(request)
154+
if err != nil {
155+
errRet = err
156+
return err
157+
}
158+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n",
159+
logId, request.GetAction(), request.ToJsonString(), response.ToJsonString())
160+
161+
return
162+
}
163+
139164
func (me *DtsService) IsolateDtsSyncJobById(ctx context.Context, jobId string) (errRet error) {
140165
logId := tccommon.GetLogId(ctx)
141166

0 commit comments

Comments
 (0)