見出し画像

TWSNMP FC:久しぶりのパニック発生

今朝は3時に自力で起きました。猫のところに行くと嬉しそうに目を輝かせて私に近づいてきました。抱っこしてあげるとゴロゴロいっていました。
昨日の続きでポーリングの動作を確認しようとTSNMP FCにアクセスするとエラーで接続できません。ログイン画面に戻ってもログインできません。
GO言語側のログを確認すると久しぶりのGOパニックが発生していました。

fatal error: concurrent map iteration and map write

goroutine 32845 [running]:
runtime.throw(0x1e0aca3, 0x26)
	/usr/local/Cellar/go/1.15.6/libexec/src/runtime/panic.go:1116 +0x72 fp=0xc000575580 sp=0xc000575550 pc=0x1037172
runtime.mapiternext(0xc000575638)
	/usr/local/Cellar/go/1.15.6/libexec/src/runtime/map.go:853 +0x554 fp=0xc000575600 sp=0xc000575580 pc=0x1012994
runtime.mapiterinit(0x1b86d20, 0xc000598450, 0xc000575638)
	/usr/local/Cellar/go/1.15.6/libexec/src/runtime/map.go:843 +0x1c5 fp=0xc000575620 sp=0xc000575600 pc=0x1012345
github.com/twsnmp/twsnmpfc/datastore.ForEachServers(0xc000575730)
	/Users/ymimacmini/prj/twsnmp/twsnmpfc/datastore/report.go:304 +0x72 fp=0xc0005756a8 sp=0xc000575620 pc=0x14ca732
github.com/twsnmp/twsnmpfc/polling.doPollingReport(0xc00001bd10)
	/Users/ymimacmini/prj/twsnmp/twsnmpfc/polling/report.go:37 +0x6f1 fp=0xc000575760 sp=0xc0005756a8 pc=0x19d0971
github.com/twsnmp/twsnmpfc/polling.doPolling(0xc00001bd10, 0x166e87fe2e010b10)

追加してレポートのポーリング機能が原因のようです。パニックの場所は、

func ForEachServers(f func(*ServerEnt) bool) {
	for _, s := range servers {
		if !f(s) {
			return
		}
	}
}

のrangeの部分でした。レポートへの情報追加とポーリングでのデータ読み出しが重なったことによるエラーでした。手抜きしてGO言語のmapを排他制御なしで使っているのが問題のようです。
この修正は、

のようにmutexを使って排他制御を自分でつけるか、それともノードなどの他のデータと同じように、

syncパッケージのMapを使うか。悩んでいます。後々の影響が大きそうなのでじっくり考えることにして今朝は修正しませんでした。

今朝は、ポーリングの細々した修正を行いました。

明日に続く。


開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。