@@ -20,20 +20,80 @@ import (
20
20
"context"
21
21
"errors"
22
22
"fmt"
23
+ "time"
23
24
24
25
machineryv1tasks "github.com/dragonflyoss/machinery/v1/tasks"
26
+ "github.com/google/uuid"
27
+ "gorm.io/gorm"
25
28
26
29
logger "d7y.io/dragonfly/v2/internal/dflog"
27
30
internaljob "d7y.io/dragonfly/v2/internal/job"
28
31
"d7y.io/dragonfly/v2/manager/metrics"
29
32
"d7y.io/dragonfly/v2/manager/models"
30
33
"d7y.io/dragonfly/v2/manager/types"
34
+ pkggc "d7y.io/dragonfly/v2/pkg/gc"
31
35
"d7y.io/dragonfly/v2/pkg/net/http"
32
36
"d7y.io/dragonfly/v2/pkg/retry"
33
37
"d7y.io/dragonfly/v2/pkg/slices"
34
38
"d7y.io/dragonfly/v2/pkg/structure"
35
39
)
36
40
41
+ const (
42
+ // DefaultGCJobPollingTimeout is the default timeout for polling GC job.
43
+ DefaultGCJobPollingTimeout = 30 * time .Minute
44
+
45
+ // DefaultGCJobPollingInterval is the default interval for polling GC job.
46
+ DefaultGCJobPollingInterval = 5 * time .Second
47
+ )
48
+
49
+ func (s * service ) CreateGCJob (ctx context.Context , json types.CreateGCJobRequest ) (* models.Job , error ) {
50
+ taskID := uuid .NewString ()
51
+ ctx = context .WithValue (ctx , pkggc .ContextKeyTaskID , taskID )
52
+ ctx = context .WithValue (ctx , pkggc .ContextKeyUserID , json .UserID )
53
+
54
+ // This is a non-block function to run the gc task, which will run the task asynchronously in the backend.
55
+ if err := s .gc .Run (ctx , json .Args .Type ); err != nil {
56
+ return nil , err
57
+ }
58
+
59
+ return s .pollingGCJob (ctx , json .Type , json .UserID , taskID )
60
+ }
61
+
62
+ func (s * service ) pollingGCJob (ctx context.Context , jobType string , userID uint , taskID string ) (* models.Job , error ) {
63
+ ctx , cancel := context .WithTimeout (ctx , DefaultGCJobPollingTimeout )
64
+ defer cancel ()
65
+
66
+ ticker := time .NewTicker (DefaultGCJobPollingInterval )
67
+ defer ticker .Stop ()
68
+
69
+ job := models.Job {}
70
+
71
+ for {
72
+ select {
73
+ case <- ctx .Done ():
74
+ return nil , fmt .Errorf ("context done: %w" , ctx .Err ())
75
+
76
+ case <- ticker .C :
77
+ if err := s .db .WithContext (ctx ).First (& job , models.Job {
78
+ Type : jobType ,
79
+ UserID : userID ,
80
+ TaskID : taskID ,
81
+ }).Error ; err != nil {
82
+ if errors .Is (err , gorm .ErrRecordNotFound ) {
83
+ continue
84
+ }
85
+
86
+ return nil , err
87
+ }
88
+
89
+ // Return the job if the job is in success or failure state, otherwise continue polling.
90
+ if job .State == machineryv1tasks .StateSuccess || job .State == machineryv1tasks .StateFailure {
91
+ return & job , nil
92
+ }
93
+ }
94
+ }
95
+ }
96
+
37
97
func (s * service ) CreateSyncPeersJob (ctx context.Context , json types.CreateSyncPeersJobRequest ) error {
38
98
schedulers , err := s .findSchedulerInClusters (ctx , json .SchedulerClusterIDs )
39
99
if err != nil {
0 commit comments