TL; DR
-
goworker.WorkerSettings.Interval
の値は無効です -
goworker.WorkerSettings.IntervalFloat
を設定しましょう -
IntervalFloat
の単位は秒
です
goworkerについて
-
Goでバックグランドジョブをキューに積みながら実行できるライブラリ
-
サーバーでレスポンスだけ返して処理は非同期実行したいときなどに役立つ
-
RubyのResque互換らしい
今回発生した問題
- 公式のGetting Startedにしたがってプログラムを実行すると、goworkerのCPU使用率が100%で高止まりすることがある
- 既知の問題らしくgoworker本家にも2016年にissueが立っている
原因
- goworkerにはワーカーの設定を記述するための
goworker.WorkerSettings
という構造体が定義されている - このうち、Jobのpolling間隔を指定する
WorkerSettings.Interval
の値がIntervalFloat
の値で常に上書きされている - そのため、
IntervalFloat
の指定がないとInterval=0となり、polling関数で遅延無しの無限ループが発生するため、CPU使用率が100%になる
参考:https://github.com/benmanns/goworker/blob/5c718f01cbd12ca8f3bd93bdcbb154264e3d89c0/flags.go#L140
解決法
-
goworker.WorkerSettings.IntervalFloat
にpollingの間隔を指定してやれば良い。 -
IntervalFloat
の単位は秒
Before
https://github.com/benmanns/goworker#getting-started から引用
worker.go
func init() {
settings := goworker.WorkerSettings{
URI: "redis://localhost:6379/",
Connections: 100,
Queues: []string{"myqueue", "delimited", "queues"},
UseNumber: true,
ExitOnComplete: false,
Concurrency: 2,
Namespace: "resque:",
Interval: 5.0,
}
goworker.SetSettings(settings)
goworker.Register("MyClass", myFunc)
}
After
worker.go
func init() {
settings := goworker.WorkerSettings{
URI: "redis://localhost:6379/",
Connections: 100,
Queues: []string{"myqueue", "delimited", "queues"},
UseNumber: true,
ExitOnComplete: false,
Concurrency: 2,
Namespace: "resque:",
- Interval: 5.0,
+ IntervalFloat: 5.0, // 5.0 sec
}
goworker.SetSettings(settings)
goworker.Register("MyClass", myFunc)
}