@@ -20,11 +20,14 @@ import (
2020
2121// Cron stores all the cron job entries.
2222type Cron struct {
23- idGen * gtype.Int64 // Used for unique name generation.
24- status * gtype.Int // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed)
25- entries * gmap.StrAnyMap // All timed task entries.
26- logger glog.ILogger // Logger, it is nil in default.
27- jobWaiter sync.WaitGroup // Graceful shutdown when cron jobs are stopped.
23+ idGen * gtype.Int64 // Used for unique name generation.
24+ status * gtype.Int // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed)
25+ entries * gmap.StrAnyMap // All timed task entries.
26+ logger glog.ILogger // Logger, it is nil in default.
27+ loggerMu sync.RWMutex
28+ jobWaiter sync.WaitGroup // Graceful shutdown when cron jobs are stopped.
29+ running bool
30+ runningLock sync.Mutex
2831}
2932
3033// New returns a new Cron object with default settings.
@@ -33,16 +36,21 @@ func New() *Cron {
3336 idGen : gtype .NewInt64 (),
3437 status : gtype .NewInt (StatusRunning ),
3538 entries : gmap .NewStrAnyMap (true ),
39+ running : true ,
3640 }
3741}
3842
3943// SetLogger sets the logger for cron.
4044func (c * Cron ) SetLogger (logger glog.ILogger ) {
45+ c .loggerMu .Lock ()
46+ defer c .loggerMu .Unlock ()
4147 c .logger = logger
4248}
4349
4450// GetLogger returns the logger in the cron.
4551func (c * Cron ) GetLogger () glog.ILogger {
52+ c .loggerMu .RLock ()
53+ defer c .loggerMu .RUnlock ()
4654 return c .logger
4755}
4856
@@ -171,7 +179,10 @@ func (c *Cron) Start(name ...string) {
171179 }
172180 }
173181 } else {
182+ c .runningLock .Lock ()
174183 c .status .Set (StatusReady )
184+ c .running = true
185+ c .runningLock .Unlock ()
175186 }
176187}
177188
@@ -185,14 +196,32 @@ func (c *Cron) Stop(name ...string) {
185196 }
186197 }
187198 } else {
199+ c .runningLock .Lock ()
188200 c .status .Set (StatusStopped )
201+ c .running = false
202+ c .runningLock .Unlock ()
189203 }
190204}
191205
192206// StopGracefully Blocks and waits all current running jobs done.
193207func (c * Cron ) StopGracefully () {
194- c .status .Set (StatusStopped )
195- c .jobWaiter .Wait ()
208+ ctx := c .StopGracefullyNonBlocking ()
209+ <- ctx .Done ()
210+ }
211+
212+ // StopGracefullyNonBlocking stops all running tasks gracefully without blocking,
213+ // returning a context that callers can use to wait for completion.
214+ func (c * Cron ) StopGracefullyNonBlocking () context.Context {
215+ ctx , cancel := context .WithCancel (context .Background ())
216+ go func () {
217+ c .runningLock .Lock ()
218+ defer c .runningLock .Unlock ()
219+ c .status .Set (StatusStopped )
220+ c .running = false
221+ c .jobWaiter .Wait ()
222+ cancel ()
223+ }()
224+ return ctx
196225}
197226
198227// Remove deletes scheduled task which named `name`.
@@ -204,7 +233,10 @@ func (c *Cron) Remove(name string) {
204233
205234// Close stops and closes current cron.
206235func (c * Cron ) Close () {
236+ c .runningLock .Lock ()
237+ defer c .runningLock .Unlock ()
207238 c .status .Set (StatusClosed )
239+ c .running = false
208240}
209241
210242// Size returns the size of the timed tasks.
0 commit comments