Revel 支持計劃任務(異步執行), 運行在請求流程的外部。比如,更新緩存數據的周期性任務,或發送電子郵件的臨時任務。
## 激活
該框架是一個可選模塊,默認是禁用的。要將它激活,需要在配置文件中添加該模塊:
~~~
module.jobs = github.com/revel/revel/modules/jobs
~~~
此外,為了訪問計劃任務的監控頁面,需要將下面的內容添加到路由文件中:
~~~
module:jobs
~~~
這條語句將插入?`/@jobs`?路由
## 選項
有兩個選項來限制計劃任務。
這個例子顯示了它們的默認值。
~~~
jobs.pool = 10 # 允許同時運行的任務數
jobs.selfconcurrent = false # 一個任務只允許一個實例
~~~
## 啟動計劃任務
應用程序啟動時, 使用[`revel.OnAppStart`](http://gorevel.cn/docs/docs/godoc/init.html#OnAppStart)?注冊一個函數來運行一個任務。Revel 在服務啟動之前,會連續啟動這些任務。 請注意,此功能實際上并未使用計劃任務模塊,它被用來提交任務,但并不阻止服務器的啟動。
~~~
func init() {
revel.OnAppStart(func() { jobs.Now(populateCache{}) })
}
~~~
## 周期性任務
任務可以被指定在任意時間運行。使用的時間表有兩個選項:
1. 一個cron時間格式
2. 固定時間間隔
Revel 使用?[cron library](https://github.com/revel/cron)?來解析時間表和任務。[cron庫的說明](https://github.com/revel/cron/blob/master/README.md)?提供了時間格式的詳細描述。
計劃任務通常使用?[`revel.OnAppStart`](http://gorevel.cn/docs/docs/godoc/init.html#OnAppStart)?鉤子進行注冊,但也可以在以后的任何時間注冊。
下面是一些例子:
~~~
import (
"github.com/revel/revel"
"github.com/revel/revel/modules/jobs/app/jobs"
"time"
)
type ReminderEmails struct {
// 過濾
}
func (e ReminderEmails) Run() {
// 查詢數據庫
// 發送電子郵件
}
func init() {
revel.OnAppStart(func() {
jobs.Schedule("0 0 0 * * ?", ReminderEmails{})
jobs.Schedule("@midnight", ReminderEmails{})
jobs.Schedule("@every 24h", ReminderEmails{})
jobs.Every(24 * time.Hour, ReminderEmails{})
})
}
~~~
## 時間表
您可以在?`app.conf`文件中配置時間表,并在任何地方引用。這可以為 crontab 格式提供易于重用和有用的說明。
在?`app.conf`定義你的時間表,:
~~~
cron.workhours_15m = 0 */15 9-17 ? * MON-FRI
~~~
使用一個cron規范指定時間表,就可以在任何地方引用它。
~~~
func init() {
revel.OnAppStart(func() {
jobs.Schedule("cron.workhours_15m", ReminderEmails{})
})
}
~~~
> 注意: cron 時間表的名字必須以 “cron.”開頭
## 臨時任務
有時候在響應用戶的一個操作時,還要處理一些事情。在這種情況下,模塊可以在某個時間運行一個任務。
模塊提供的唯一控制是等待多長時間運行任務。
~~~
type AppController struct { *revel.Controller }
func (c AppController) Action() revel.Result {
// 處理請求
...
// 立即發送電子郵件(異步)
jobs.Now(SendConfirmationEmail{})
// 或者,一分鐘后發送電子郵件(異步)。
jobs.In(time.Minute, SendConfirmationEmail{})
}
~~~
## 注冊函數
通過使用`jobs.Func`類型包裝一個`func()`函數,來注冊一個任務。例如:
~~~
func sendReminderEmails() {
// 查詢數據庫
// 發送電子郵件
}
func init() {
revel.OnAppStart(func() {
jobs.Schedule("@midnight", jobs.Func(sendReminderEmails))
})
}
~~~
## 任務狀態
模塊提供了一個狀態頁面,用來顯示任務的運行狀態(**IDLE**?或?**RUNNING**), 以及之前和下次運行時間。

為了安全起見,狀態頁面僅接受127.0.0.1發起的請求。
## 限制池的大小
任務模塊配置,用來限制同一時間運行的任務數量。這允許開發人員限制可能會潛在地使用異步任務的資源 - 通常是交互式的響應高于異步處理。當池中正在運行的任務已滿,新的任務將阻塞,直到正在運行的任務完成。
注意事項:計劃任務在一個channel上阻塞,為等待的goroutines實現了一個FIFO (但沒有指定/需要這樣).?[參考這里的討論](https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/CPwv8WlqKag).
## 開發狀態
* 允許使用HTTP基本身份驗證憑據訪問任務狀態頁面
* 允許管理員從狀態頁面以交互方式執行預定任務
* 支持更多的頁面屬性,例如:池的大小,任務隊列長度等。