@@ -25,12 +25,18 @@ const (
2525 dcronStateUpgrade = "dcronStateUpgrade"
2626)
2727
28+ var (
29+ ErrJobExist = errors .New ("jobName already exist" )
30+ ErrJobNotExist = errors .New ("jobName not exist" )
31+ ErrJobWrongNode = errors .New ("job is not running in this node" )
32+ )
33+
2834type RecoverFuncType func (d * Dcron )
2935
3036// Dcron is main struct
3137type Dcron struct {
3238 jobs map [string ]* JobWarpper
33- jobsRWMut sync.Mutex
39+ jobsRWMut sync.RWMutex
3440
3541 ServerName string
3642 nodePool INodePool
@@ -48,6 +54,8 @@ type Dcron struct {
4854
4955 recentJobs IRecentJobPacker
5056 state atomic.Value
57+
58+ runningLocally bool
5159}
5260
5361// NewDcron create a Dcron
@@ -68,7 +76,9 @@ func NewDcronWithOption(serverName string, driver driver.DriverV2, dcronOpts ...
6876 }
6977
7078 dcron .cr = cron .New (dcron .crOptions ... )
71- dcron .nodePool = NewNodePool (serverName , driver , dcron .nodeUpdateDuration , dcron .hashReplicas , dcron .logger )
79+ if ! dcron .runningLocally {
80+ dcron .nodePool = NewNodePool (serverName , driver , dcron .nodeUpdateDuration , dcron .hashReplicas , dcron .logger )
81+ }
7282 return dcron
7383}
7484
@@ -110,9 +120,9 @@ func (d *Dcron) addJob(jobName, cronStr string, job Job) (err error) {
110120 d .jobsRWMut .Lock ()
111121 defer d .jobsRWMut .Unlock ()
112122 if _ , ok := d .jobs [jobName ]; ok {
113- return errors . New ( "jobName already exist" )
123+ return ErrJobExist
114124 }
115- innerJob := JobWarpper {
125+ innerJob := & JobWarpper {
116126 Name : jobName ,
117127 CronStr : cronStr ,
118128 Job : job ,
@@ -123,11 +133,11 @@ func (d *Dcron) addJob(jobName, cronStr string, job Job) (err error) {
123133 return err
124134 }
125135 innerJob .ID = entryID
126- d .jobs [jobName ] = & innerJob
136+ d .jobs [jobName ] = innerJob
127137 return nil
128138}
129139
130- // Remove Job
140+ // Remove Job by jobName
131141func (d * Dcron ) Remove (jobName string ) {
132142 d .jobsRWMut .Lock ()
133143 defer d .jobsRWMut .Unlock ()
@@ -138,7 +148,71 @@ func (d *Dcron) Remove(jobName string) {
138148 }
139149}
140150
151+ // Get job by jobName
152+ // if this jobName not exist, will return error.
153+ //
154+ // if `thisNodeOnly` is true
155+ // if this job is not available in this node, will return error.
156+ // otherwise return the struct of JobWarpper whose name is jobName.
157+ func (d * Dcron ) GetJob (jobName string , thisNodeOnly bool ) (* JobWarpper , error ) {
158+ d .jobsRWMut .RLock ()
159+ defer d .jobsRWMut .RUnlock ()
160+
161+ job , ok := d .jobs [jobName ]
162+ if ! ok {
163+ d .logger .Warnf ("job: %s, not exist" , jobName )
164+ return nil , ErrJobNotExist
165+ }
166+ if ! thisNodeOnly {
167+ return job , nil
168+ }
169+ isRunningHere , err := d .nodePool .CheckJobAvailable (jobName )
170+ if err != nil {
171+ return nil , err
172+ }
173+ if ! isRunningHere {
174+ return nil , ErrJobWrongNode
175+ }
176+ return job , nil
177+ }
178+
179+ // Get job list.
180+ //
181+ // if `thisNodeOnly` is true
182+ // return all jobs available in this node.
183+ // otherwise return all jobs added to dcron.
184+ //
185+ // we never return nil. If there is no job.
186+ // this func will return an empty slice.
187+ func (d * Dcron ) GetJobs (thisNodeOnly bool ) []* JobWarpper {
188+ d .jobsRWMut .RLock ()
189+ defer d .jobsRWMut .RUnlock ()
190+
191+ ret := make ([]* JobWarpper , 0 )
192+ for _ , v := range d .jobs {
193+ var (
194+ isRunningHere bool
195+ ok bool = true
196+ err error
197+ )
198+ if thisNodeOnly {
199+ isRunningHere , err = d .nodePool .CheckJobAvailable (v .Name )
200+ if err != nil {
201+ continue
202+ }
203+ ok = isRunningHere
204+ }
205+ if ok {
206+ ret = append (ret , v )
207+ }
208+ }
209+ return ret
210+ }
211+
141212func (d * Dcron ) allowThisNodeRun (jobName string ) (ok bool ) {
213+ if d .runningLocally {
214+ return true
215+ }
142216 ok , err := d .nodePool .CheckJobAvailable (jobName )
143217 if err != nil {
144218 d .logger .Errorf ("allow this node run error, err=%v" , err )
@@ -165,12 +239,14 @@ func (d *Dcron) Start() {
165239 d .RecoverFunc (d )
166240 }
167241 if atomic .CompareAndSwapInt32 (& d .running , dcronStopped , dcronRunning ) {
168- if err := d .startNodePool (); err != nil {
169- atomic .StoreInt32 (& d .running , dcronStopped )
170- return
242+ if ! d .runningLocally {
243+ if err := d .startNodePool (); err != nil {
244+ atomic .StoreInt32 (& d .running , dcronStopped )
245+ return
246+ }
247+ d .logger .Infof ("dcron started, nodeID is %s" , d .nodePool .GetNodeID ())
171248 }
172249 d .cr .Start ()
173- d .logger .Infof ("dcron started, nodeID is %s" , d .nodePool .GetNodeID ())
174250 } else {
175251 d .logger .Infof ("dcron have started" )
176252 }
@@ -183,11 +259,13 @@ func (d *Dcron) Run() {
183259 d .RecoverFunc (d )
184260 }
185261 if atomic .CompareAndSwapInt32 (& d .running , dcronStopped , dcronRunning ) {
186- if err := d .startNodePool (); err != nil {
187- atomic .StoreInt32 (& d .running , dcronStopped )
188- return
262+ if ! d .runningLocally {
263+ if err := d .startNodePool (); err != nil {
264+ atomic .StoreInt32 (& d .running , dcronStopped )
265+ return
266+ }
267+ d .logger .Infof ("dcron running, nodeID is %s" , d .nodePool .GetNodeID ())
189268 }
190- d .logger .Infof ("dcron running, nodeID is %s" , d .nodePool .GetNodeID ())
191269 d .cr .Run ()
192270 } else {
193271 d .logger .Infof ("dcron already running" )
@@ -205,7 +283,9 @@ func (d *Dcron) startNodePool() error {
205283// Stop job
206284func (d * Dcron ) Stop () {
207285 tick := time .NewTicker (time .Millisecond )
208- d .nodePool .Stop (context .Background ())
286+ if ! d .runningLocally {
287+ d .nodePool .Stop (context .Background ())
288+ }
209289 for range tick .C {
210290 if atomic .CompareAndSwapInt32 (& d .running , dcronRunning , dcronStopped ) {
211291 d .cr .Stop ()
0 commit comments