hikarie.goに参加してきた話。revelがどのようにファイル更新によるリロードを実現しているか #golangjp #hikarie_go

先日hikarie.go #2 http://connpass.com/event/7914/ に参加してきました。 hikarie.goで使用されていた、ハンズオン形式で分かりやすくい資料はこちら
https://github.com/yosuke-furukawa/golang-study @yosuke_furukawaさん++!

で、その中でどういう質問だったか曖昧なのですが、
要点はファイルを更新した際に、コンパイルしなおして、Webを再表示するみたいなことはできるのか?
(Gae/Goだとできてたっけ?曖昧)という旨の話があって、revelはそれやってたなーという話

revelがどのようにファイル更新によるリロードを実現しているか。


フルスタックなWebふれーむわーくrevel
https://github.com/revel

revelは本体とcmdが分かれている。
https://github.com/revel/cmd

run.go

https://github.com/revel/cmd/blob/master/revel/run.go
を見てみると、watchモードだったら
harness.NewHarness().Run() // Never returns.
みたいな記述があるので、revel.harness.NewHarnessを見に行く。

Harness.go

https://github.com/revel/revel/blob/master/harness/harness.go
NewHarness は *Harness を返してくる。
同ファイル内にてメソッドを定義している。
https://github.com/revel/revel/blob/master/harness/harness.go#L153
func (h *Harness) Run()
で、Run()内で以下のような、Pathを渡している箇所がある。
paths = append(paths, revel.CodePaths...)
 watcher = revel.NewWatcher()
 watcher.Listen(h, paths...)
次はrevel.NewWatcher()を追っていく

watcher.go

https://github.com/revel/revel/blob/master/watcher.go

func (w *Watcher) Listen(listener Listener, roots ...string) {
なるほど、WatcherはListenerと監視するディレクトリを受け取るようだ。
fsnotify.NewWatcher()がいかにもなので、先にこれを見てみよう↓

github.com/howeyc/fsnotify

https://github.com/howeyc/fsnotify
と、ここまで来て、
File system notification for Go というライブラリにたどり着く
なるほど。ファイルのを監視して通知してくれるんやな。
で、今度はファイルシステムの変更があったら何をするかという話になるんだけど、
Listener型はRefresh()を持っていればListenerと見なせる。という形になっている。
Harness.goでWatcherに自分自身を渡しているのでHarness.goのRefresh()が実行される寸法
type Listener interface {
 // Refresh is invoked by the watcher on relevant filesystem events.
 // If the listener returns an error, it is served to the user on the current request.
 Refresh() *Error
}

harness.go

https://github.com/revel/revel/blob/master/harness/harness.go Harnessには確かにRefreshというメソッドが定義してある。そして、revel.TRACE.Println("Rebuild")
って記述もあるので、そろそろゴールっぽい。
// Rebuild the Revel application and run it on the given port.
func (h *Harness) Refresh() (err *revel.Error) {

build.go

https://github.com/revel/revel/blob/master/harness/build.go ここで、main.goやroutes.goの再構成が行われている!
// GENERATED CODE - DO NOT EDIT
と書かれたテンプレートも同ファイルに記述してある。


と、若干駆け足だったけど、revelがどんな感じで監視&更新してるかをざっと見てみました。
github.com/howeyc/fsnotifyをなにかのツールで使ってみたい欲があります。

あと、Goのコードはルールさえ覚えておけば追いやすい感があります。 結論が出てない感じですが、眠くなってしまう前にBlogに投下!

0 件のコメント :