This is a creation in Article, where the information may have evolved or changed.
Cron timed Tasks
Project Address: Https://github.com/EDDYCJY/go ...
If you have any help, please feel free to order a Star or
In real-world applications, the use of timed tasks is common. Have you ever had a question about Golang how to do a timed task, or is it a poll?
In this article we will talk about Cron in conjunction with our project
Introduced
We will use the Cron package, which implements the Cron Spec parser and task Runner, simply to include the functions required for the scheduled task
Cron-expression format
Field name |
is required |
allowable Values |
allowed special characters |
Seconds (Seconds) |
Yes |
0-59 |
* / , - |
Points (Minutes) |
Yes |
0-59 |
* / , - |
Time (Hours) |
Yes |
0-23 |
* / , - |
One of the one months (day of month) |
Yes |
1-31 |
* / , - ? |
Monthly (month) |
Yes |
1-12 or Jan-dec |
* / , - |
Day of the week (Day of week) |
Yes |
0-6 or Sun-sat |
* / , - ? |
A cron expression represents a set of times, using 6 space-delimited fields
Can notice that the Golang Cron more than Crontab a second level, and then meet the second-level requirements of the time is convenient
Cron Special Characters
1. asterisk (*)
An asterisk indicates that all values of the field will be matched
2. Slash (/)
A slash user describes the increment of the range, expressed as "n-max/x", the form of first-last/x, for example 3-59/15 represents the third minute at this time and thereafter every 15 minutes, to 59 minutes. Starting with N, the increment is used until the end of that particular range. It won't repeat
3, comma (,)
Commas are used to separate items in the list. For example, using "Mon,wed,fri" on day of week will mean Monday, Wednesday and Friday
4. Hyphen (-)
Hyphens are used to define ranges. For example, 9-17 means every hour from 9 o'clock in the morning to 5 o'clock in the afternoon
5. Question mark (?)
Do not specify a value, instead of "*", similar to the existence of "_", it is not difficult to understand
Pre-defined Cron schedule
input |
Brief Introduction |
equivalent |
@yearly (or @annually) |
Run once at midnight January 1 |
0 0 0 1 1 * |
@monthly |
Every month at midnight, the first month of each month runs |
0 0 0 1 |
@weekly |
Once a week, run at midnight in Sunday |
0 0 0 0 |
@daily (or @midnight) |
Run once a day at midnight |
0 0 0 * |
@hourly |
Run once per hour |
0 0 |
Installation
$ go get -u github.com/robfig/cron
Practice
In the previous chapter gin practice serial 10 Custom GORM callbacks, we used the GORM callback to implement soft deletion, but also introduced another problem
Is how I hard delete, when do I hard delete? This is often related to business scenarios and is roughly
- Another set of hard-deleted interfaces
- Timed task Cleanup (or transfer, backup) invalid data
Here we use the second solution to practice
Writing hard-deleted code
Open the Tag.go, Article.go file under the models directory, and add the following code separately
1, Tag.go
func CleanAllTag() bool { db.Unscoped().Where("deleted_on != ? ", 0).Delete(&Tag{}) return true}
2, Article.go
func CleanAllArticle() bool { db.Unscoped().Where("deleted_on != ? ", 0).Delete(&Article{}) return true}
Note the hard delete to use Unscoped()
, which is the GORM convention
Write cron
Create a new Cron.go file under the project root to write the code for the timed task and write the contents of the file
package mainimport ( "time" "log" "github.com/robfig/cron" "github.com/EDDYCJY/go-gin-example/models")func main() { log.Println("Starting...") c := cron.New() c.AddFunc("* * * * * *", func() { log.Println("Run models.CleanAllTag...") models.CleanAllTag() }) c.AddFunc("* * * * * *", func() { log.Println("Run models.CleanAllArticle...") models.CleanAllArticle() }) c.Start() t1 := time.NewTimer(time.Second * 10) for { select { case <-t1.C: t1.Reset(time.Second * 10) } }}
In this program, we do the following things
1, Cron. New ()
A new (blank) Cron job is created based on local time runner
func New() *Cron { return NewWithLocation(time.Now().Location())}// NewWithLocation returns a new Cron job runner.func NewWithLocation(location *time.Location) *Cron { return &Cron{ entries: nil, add: make(chan *Entry), stop: make(chan struct{}), snapshot: make(chan []*Entry), running: false, ErrorLog: nil, location: location, }}
2, C.addfunc ()
Addfunc will add a func to the Cron job runner to run on a given schedule
func (c *Cron) AddJob(spec string, cmd Job) error { schedule, err := Parse(spec) if err != nil { return err } c.Schedule(schedule, cmd) return nil}
The timesheet will be parsed first, and if a problem is filled, err will be added directly to the Schedule queue for execution
func (c *Cron) Schedule(schedule Schedule, cmd Job) { entry := &Entry{ Schedule: schedule, Job: cmd, } if !c.running { c.entries = append(c.entries, entry) return } c.add <- entry}
3, C.start ()
Starts the Cron scheduler in the currently executing program. In fact, the main body here is Goroutine + for + select + Timer scheduling control OH
func (c *Cron) Run() { if c.running { return } c.running = true c.run()}
4, time. Newtimer + for + select + T1. Reset
If you are a beginner, you will probably have questions, what is it for?
(1) time. Newtimer
A new timer is created, and a channel message is sent after you set the time D
(2) for + Select
Block Select waits for Channel
(3) T1. Reset
Resets the timer to start the timer again.
(Note that this article applies to "T.C has been taken away and can be used directly with Reset")
In general, this procedure is designed to block the main program, I hope you have questions to think, there is no other way?
Yes, you select{}
can directly complete this requirement:)
Verify
$ go run cron.go 2018/04/29 17:03:34 [info] replacing callback `gorm:update_time_stamp` from /Users/eddycjy/go/src/github.com/EDDYCJY/go-gin-example/models/models.go:562018/04/29 17:03:34 [info] replacing callback `gorm:update_time_stamp` from /Users/eddycjy/go/src/github.com/EDDYCJY/go-gin-example/models/models.go:572018/04/29 17:03:34 [info] replacing callback `gorm:delete` from /Users/eddycjy/go/src/github.com/EDDYCJY/go-gin-example/models/models.go:582018/04/29 17:03:34 Starting...2018/04/29 17:03:35 Run models.CleanAllArticle...2018/04/29 17:03:35 Run models.CleanAllTag...2018/04/29 17:03:36 Run models.CleanAllArticle...2018/04/29 17:03:36 Run models.CleanAllTag...2018/04/29 17:03:37 Run models.CleanAllTag...2018/04/29 17:03:37 Run models.CleanAllArticle...
Check output log is normal, simulate soft deleted data, scheduled task work OK
Summary
Timing tasks are common, I hope you can understand golang how to achieve a simple scheduled task scheduling management
Can not rely on the system's Crontab settings, which day to use it?
Reference
Sample code for this series
Catalog of this series
- Gin Practice Serial One Golang introduction and environment installation
- Gin Practice Two Build blog API ' s (i)
- Gin Practice three Build blog API ' s (ii)
- Gin Practice Four Build blog API ' s (iii)
- Gin Practice Five Build blog API ' s (iv)
- Gin Practice Six Build blog API ' s (v)
- Gin Practice serial Seven Golang graceful restart HTTP service
- Gin practice serial Eight for it plus swagger
- Gin practice nine deploying Golang applications to Docker
- Gin Practice serial 10 Custom GORM callbacks
- Gin Practice Serial 11 Cron timed tasks
- Gin Practice Golang Cross-compiling