実際の開発プロセスでは、我々は時々 、いくつかの定期的なタスクを記述する必要があります。もちろん、我々は使用することができますcrontab
我々のニーズを達成するためのコマンドを。しかし、この方法では、カスタマイズシーンのいくつかを満たしていない、それは特定のオペレーティング・システム環境に依存します。
定期的なタスク
ではgolang
、私たちは、使用できるのcronを私たちの要望定期的なタスクを達成するために。次のように彼の使用は、特定のコードは非常に簡単です:
package main
import(
"fmt"
cron "github.com/robfig/cron/v3"
)
func main() {
crontab := cron.New()
task := func() {
fmt.Println("hello world")
}
// 添加定时任务, * * * * * 是 crontab,表示每分钟执行一次
crontab.AddFunc("* * * * *", task)
// 启动定时器
crontab.Start()
// 定时任务是另起协程执行的,这里使用 select 简答阻塞.实际开发中需要
// 根据实际情况进行控制
select {}
}
注意:
- 新しい()関数は、次のような複数の初期化オプションをサポートしています
cron.WithPanicLogger
- 別のコルーチンの実行からのタイミングタスク
上記は、cronの例を使用するのが最も簡単で、使用状況のより詳細な理解が必要な場合、あなたは公式ドキュメントと例を参照することができます。
カスタムパッケージ
上記に基づいてメソッドを使用して、私の実際の需要に基づいて、私のcron
ライブラリは、主に以下のいくつかの要件の実現のため、簡易包装ありました。
- すべての時限タスク、定期的なタスクの数を記録する必要性および関連情報を管理します
- スケジュールされたタスクを停止します
- サポートは、関数型とインタフェースタイプのタスクを追加します
いくつかの単語の男は、直接コードに取り付けた、言いました:
package main
import (
"fmt"
"sync"
"github.com/pkg/errors"
cron "github.com/robfig/cron/v3"
)
// Crontab crontab manager
type Crontab struct {
inner *cron.Cron
ids map[string]cron.EntryID
mutex sync.Mutex
}
// NewCrontab new crontab
func NewCrontab() *Crontab {
return &Crontab{
inner: cron.New(),
ids: make(map[string]cron.EntryID),
}
}
// IDs ...
func (c *Crontab) IDs() []string {
c.mutex.Lock()
defer c.mutex.Unlock()
validIDs := make([]string, 0, len(c.ids))
invalidIDs := make([]string, 0)
for sid, eid := range c.ids {
if e := c.inner.Entry(eid); e.ID != eid {
invalidIDs = append(invalidIDs, sid)
continue
}
validIDs = append(validIDs, sid)
}
for _, id := range invalidIDs {
delete(c.ids, id)
}
return validIDs
}
// Start start the crontab engine
func (c *Crontab) Start() {
c.inner.Start()
}
// Stop stop the crontab engine
func (c *Crontab) Stop() {
c.inner.Stop()
}
// DelByID remove one crontab task
func (c *Crontab) DelByID(id string) {
c.mutex.Lock()
defer c.mutex.Unlock()
eid, ok := c.ids[id]
if !ok {
return
}
c.inner.Remove(eid)
delete(c.ids, id)
}
// AddByID add one crontab task
// id is unique
// spec is the crontab expression
func (c *Crontab) AddByID(id string, spec string, cmd cron.Job) error {
c.mutex.Lock()
defer c.mutex.Unlock()
if _, ok := c.ids[id]; ok {
return errors.Errorf("crontab id exists")
}
eid, err := c.inner.AddJob(spec, cmd)
if err != nil {
return err
}
c.ids[id] = eid
return nil
}
// AddByFunc add function as crontab task
func (c *Crontab) AddByFunc(id string, spec string, f func()) error {
c.mutex.Lock()
defer c.mutex.Unlock()
if _, ok := c.ids[id]; ok {
return errors.Errorf("crontab id exists")
}
eid, err := c.inner.AddFunc(spec, f)
if err != nil {
return err
}
c.ids[id] = eid
return nil
}
// IsExists check the crontab task whether existed with job id
func (c *Crontab) IsExists(jid string) bool {
_, exist := c.ids[jid]
return exist
}
コードを達成するのは非常に簡単で、各機能の役割は、上記のパッケージで、シンプルで実用的な以下のコメントを参照することができます:
type testTask struct {
}
func (t *testTask) Run() {
fmt.Println("hello world")
}
func main() {
crontab := NewCrontab()
// 实现接口的方式添加定时任务
task := &testTask{}
if err := crontab.AddByID("1", "* * * * *", task); err != nil {
fmt.Printf("error to add crontab task:%s", err)
os.Exit(-1)
}
// 添加函数作为定时任务
taskFunc := func() {
fmt.Println("hello world")
}
if err := crontab.AddByFunc("2", "* * * * *", taskFunc); err != nil {
fmt.Printf("error to add crontab task:%s", err)
os.Exit(-1)
}
crontab.Start()
select {}
}
注意:
- タスクIDが一意である、実際の開発は、UUIDを使用することができます
- このパッケージは、セキュリティによって複雑になります
不十分:
- 初期化パラメータをサポートしていません
- タイミング・エラー・コレクション・タスクのcronジョブエラー場合、エラー情報を取得することができるはずです(この場合はパニックにならないで間違っています)
- パニック回復操作を参照することができ
withChain
、かつcron.Recover
追伸
cronと、より複雑な使用法の原則の詳細な実装を解析する次