github.com/gogf/gf@v1.16.9/os/gcron/gcron_cron.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gcron 8 9 import ( 10 "time" 11 12 "github.com/gogf/gf/container/garray" 13 "github.com/gogf/gf/container/gmap" 14 "github.com/gogf/gf/container/gtype" 15 "github.com/gogf/gf/os/glog" 16 "github.com/gogf/gf/os/gtimer" 17 ) 18 19 type Cron struct { 20 idGen *gtype.Int64 // Used for unique name generation. 21 status *gtype.Int // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed) 22 entries *gmap.StrAnyMap // All timed task entries. 23 logger *glog.Logger // Logger, it is nil in default. 24 25 // Logging path(folder). 26 // Deprecated, use logger instead. 27 logPath *gtype.String 28 29 // Logging level. 30 // Deprecated, use logger instead. 31 logLevel *gtype.Int 32 } 33 34 // New returns a new Cron object with default settings. 35 func New() *Cron { 36 return &Cron{ 37 idGen: gtype.NewInt64(), 38 status: gtype.NewInt(StatusRunning), 39 entries: gmap.NewStrAnyMap(true), 40 logPath: gtype.NewString(), 41 logLevel: gtype.NewInt(glog.LEVEL_PROD), 42 } 43 } 44 45 // SetLogger sets the logger for cron. 46 func (c *Cron) SetLogger(logger *glog.Logger) { 47 c.logger = logger 48 } 49 50 // GetLogger returns the logger in the cron. 51 func (c *Cron) GetLogger() *glog.Logger { 52 return c.logger 53 } 54 55 // SetLogPath sets the logging folder path. 56 // Deprecated, use SetLogger instead. 57 func (c *Cron) SetLogPath(path string) { 58 c.logPath.Set(path) 59 } 60 61 // GetLogPath return the logging folder path. 62 // Deprecated, use GetLogger instead. 63 func (c *Cron) GetLogPath() string { 64 return c.logPath.Val() 65 } 66 67 // SetLogLevel sets the logging level. 68 // Deprecated, use SetLogger instead. 69 func (c *Cron) SetLogLevel(level int) { 70 c.logLevel.Set(level) 71 } 72 73 // GetLogLevel returns the logging level. 74 // Deprecated, use GetLogger instead. 75 func (c *Cron) GetLogLevel() int { 76 return c.logLevel.Val() 77 } 78 79 // AddEntry creates and returns a new Entry object. 80 func (c *Cron) AddEntry(pattern string, job func(), times int, singleton bool, name ...string) (*Entry, error) { 81 var ( 82 entryName = "" 83 infinite = false 84 ) 85 if len(name) > 0 { 86 entryName = name[0] 87 } 88 if times <= 0 { 89 infinite = true 90 } 91 return c.doAddEntry(addEntryInput{ 92 Name: entryName, 93 Job: job, 94 Times: times, 95 Pattern: pattern, 96 Singleton: singleton, 97 Infinite: infinite, 98 }) 99 } 100 101 // Add adds a timed task. 102 // A unique `name` can be bound with the timed task. 103 // It returns and error if the `name` is already used. 104 func (c *Cron) Add(pattern string, job func(), name ...string) (*Entry, error) { 105 return c.AddEntry(pattern, job, -1, false, name...) 106 } 107 108 // AddSingleton adds a singleton timed task. 109 // A singleton timed task is that can only be running one single instance at the same time. 110 // A unique `name` can be bound with the timed task. 111 // It returns and error if the `name` is already used. 112 func (c *Cron) AddSingleton(pattern string, job func(), name ...string) (*Entry, error) { 113 return c.AddEntry(pattern, job, -1, true, name...) 114 } 115 116 // AddTimes adds a timed task which can be run specified times. 117 // A unique `name` can be bound with the timed task. 118 // It returns and error if the `name` is already used. 119 func (c *Cron) AddTimes(pattern string, times int, job func(), name ...string) (*Entry, error) { 120 return c.AddEntry(pattern, job, times, false, name...) 121 } 122 123 // AddOnce adds a timed task which can be run only once. 124 // A unique `name` can be bound with the timed task. 125 // It returns and error if the `name` is already used. 126 func (c *Cron) AddOnce(pattern string, job func(), name ...string) (*Entry, error) { 127 return c.AddEntry(pattern, job, 1, false, name...) 128 } 129 130 // DelayAddEntry adds a timed task after `delay` time. 131 func (c *Cron) DelayAddEntry(delay time.Duration, pattern string, job func(), times int, singleton bool, name ...string) { 132 gtimer.AddOnce(delay, func() { 133 if _, err := c.AddEntry(pattern, job, times, singleton, name...); err != nil { 134 panic(err) 135 } 136 }) 137 } 138 139 // DelayAdd adds a timed task after `delay` time. 140 func (c *Cron) DelayAdd(delay time.Duration, pattern string, job func(), name ...string) { 141 gtimer.AddOnce(delay, func() { 142 if _, err := c.Add(pattern, job, name...); err != nil { 143 panic(err) 144 } 145 }) 146 } 147 148 // DelayAddSingleton adds a singleton timed task after `delay` time. 149 func (c *Cron) DelayAddSingleton(delay time.Duration, pattern string, job func(), name ...string) { 150 gtimer.AddOnce(delay, func() { 151 if _, err := c.AddSingleton(pattern, job, name...); err != nil { 152 panic(err) 153 } 154 }) 155 } 156 157 // DelayAddOnce adds a timed task after `delay` time. 158 // This timed task can be run only once. 159 func (c *Cron) DelayAddOnce(delay time.Duration, pattern string, job func(), name ...string) { 160 gtimer.AddOnce(delay, func() { 161 if _, err := c.AddOnce(pattern, job, name...); err != nil { 162 panic(err) 163 } 164 }) 165 } 166 167 // DelayAddTimes adds a timed task after `delay` time. 168 // This timed task can be run specified times. 169 func (c *Cron) DelayAddTimes(delay time.Duration, pattern string, times int, job func(), name ...string) { 170 gtimer.AddOnce(delay, func() { 171 if _, err := c.AddTimes(pattern, times, job, name...); err != nil { 172 panic(err) 173 } 174 }) 175 } 176 177 // Search returns a scheduled task with the specified `name`. 178 // It returns nil if not found. 179 func (c *Cron) Search(name string) *Entry { 180 if v := c.entries.Get(name); v != nil { 181 return v.(*Entry) 182 } 183 return nil 184 } 185 186 // Start starts running the specified timed task named `name`. 187 // If no`name` specified, it starts the entire cron. 188 func (c *Cron) Start(name ...string) { 189 if len(name) > 0 { 190 for _, v := range name { 191 if entry := c.Search(v); entry != nil { 192 entry.Start() 193 } 194 } 195 } else { 196 c.status.Set(StatusReady) 197 } 198 } 199 200 // Stop stops running the specified timed task named `name`. 201 // If no`name` specified, it stops the entire cron. 202 func (c *Cron) Stop(name ...string) { 203 if len(name) > 0 { 204 for _, v := range name { 205 if entry := c.Search(v); entry != nil { 206 entry.Stop() 207 } 208 } 209 } else { 210 c.status.Set(StatusStopped) 211 } 212 } 213 214 // Remove deletes scheduled task which named `name`. 215 func (c *Cron) Remove(name string) { 216 if v := c.entries.Get(name); v != nil { 217 v.(*Entry).Close() 218 } 219 } 220 221 // Close stops and closes current cron. 222 func (c *Cron) Close() { 223 c.status.Set(StatusClosed) 224 } 225 226 // Size returns the size of the timed tasks. 227 func (c *Cron) Size() int { 228 return c.entries.Size() 229 } 230 231 // Entries return all timed tasks as slice(order by registered time asc). 232 func (c *Cron) Entries() []*Entry { 233 array := garray.NewSortedArraySize(c.entries.Size(), func(v1, v2 interface{}) int { 234 entry1 := v1.(*Entry) 235 entry2 := v2.(*Entry) 236 if entry1.Time.Nanosecond() > entry2.Time.Nanosecond() { 237 return 1 238 } 239 return -1 240 }, true) 241 c.entries.RLockFunc(func(m map[string]interface{}) { 242 for _, v := range m { 243 array.Add(v.(*Entry)) 244 } 245 }) 246 entries := make([]*Entry, array.Len()) 247 array.RLockFunc(func(array []interface{}) { 248 for k, v := range array { 249 entries[k] = v.(*Entry) 250 } 251 }) 252 return entries 253 }