Slide 1

Slide 1 text

© DMM © DMM CONFIDENTIAL Airパッケージの深掘り 〜変更検知の仕組み〜 大野 直哉 メディア基盤開発部 配信基盤グループ DMM.go #11

Slide 2

Slide 2 text

© DMM 自己紹介 名前: 大野直哉 今年4月に入社した25新卒 8月から配信基盤グループに所属 2

Slide 3

Slide 3 text

© DMM 発表動機 ➢ これまでGoの開発でAirを導入することが多かった ○ 新卒の技術研修でもAirを利用していた ➢ そもそもAirはどのようにして動いているのか? 3 Airのソースコードを読んで調べてみました 今日はその内容について発表します

Slide 4

Slide 4 text

© DMM 目次 1. Airの概要 2. 変更検知の概要 3. Watcherの内部処理の詳細 4

Slide 5

Slide 5 text

© DMM Airの概要 1. Airの概要 2. 変更検知の概要 3. Watcherの内部処理の詳細 5

Slide 6

Slide 6 text

© DMM Airとは? ➢ Goのライブリロードのツール ○ ライブリロードとは ■ 手動でアプリケーションを停止、再起動せずにコードの変更がリアルタイムに反映される仕 組み ➢ Airを導入することで開発速度と開発体験を向上させることができる 6 https://github.com/air-verse/air

Slide 7

Slide 7 text

© DMM Airとは? 実際の動作のログ 7 main.goを変更を検知して ビルド、リロードが実行され ている

Slide 8

Slide 8 text

© DMM Airの全体図 8 リロード ビルド 変更検知 Air ソースコード 実行環境 開発者 ←←👀

Slide 9

Slide 9 text

© DMM Airの全体図 9 リロード ビルド 変更検知 Air ソースコード 実行環境 開発者 ←←👀 どのようにしてソースコードの 監視を実現しているか?

Slide 10

Slide 10 text

© DMM 変更検知の概要 1. Airの概要 2. 変更検知の概要 3. Watcherの内部処理の詳細 10

Slide 11

Slide 11 text

© DMM ➢ Watcherから通知を受け取るとビルド以降の処理が走る Watcher 11 変更検知 Watcher リロード チャネル main goroutine ビルド goroutine コードの変更を監視

Slide 12

Slide 12 text

© DMM Watcher 12 Watcher 実行ディレクトリ直下の全ての Goファイルを監視 監視対象は設定ファイルから変更可能

Slide 13

Slide 13 text

© DMM Watcher 13 Watcher ファイルが変更されると、main goroutineに通知 main.go main.goが変更

Slide 14

Slide 14 text

© DMM Watcher 14 Watcher Watcherはどのように 変更を検知しているのか?

Slide 15

Slide 15 text

© DMM hugoのWatcher ➢ AirのWatcherはhugoを利用 ➢ hugoのfilenotifyで定義された Watcherを呼び出す 15 https://github.com/air-verse/air/ blob/master/runner/watcher.go

Slide 16

Slide 16 text

© DMM hugoとは? ➢ Goの静的サイト作成用のパッケージ ➢ コンテンツをマークダウンで管理する ○ コンテンツの変更を検知してリロードされて最新のコンテンツが反映される 16 https://github.com/gohugoio/hugo この機能をAirで利用

Slide 17

Slide 17 text

© DMM hugoのWatcher ➢ hugoには二種類のWatcherが存在する ○ Watcher自体のインタフェースは共通 17 ➢ EventWatcher OSの機能を利用してコードの変 更をリアルタイムで検知する ➢ PollingWatcher 一定周期でコードをチェックを回し て変更を検知する EventWatcherを利用できないケー スで使用 https://github.com/gohugoio/hugo/blob/ master/watcher/filenotify/filenotify.go

Slide 18

Slide 18 text

© DMM hugoのWatcher ➢ hugoには二種類のWatcherが存在する 18 ➢ EventWatcher ファイルの変更をリアルタイムで検 知する ➢ PollingWatcher 一定周期でファイルをチェックを回 して変更を検知する AirではどちらのWatcherも利用可能 falseの場合はEventWatcher trueの場合はPollingWatcher ※デフォルトはfalse

Slide 19

Slide 19 text

© DMM hugoのWatcher ➢ hugoには二種類のWatcherが存在する 19 ➢ EventWatcher ファイルの変更をリアルタイムで検 知する ➢ PollingWatcher 一定周期でファイルをチェックを回 して変更を検知する それぞれのWatcherはどのように 変更を検知しているか?

Slide 20

Slide 20 text

© DMM Watcherの内部処理の詳細 1. Airの概要 2. 変更検知の概要 3. Watcherの内部処理の詳細 20

Slide 21

Slide 21 text

© DMM EventWatcher ➢ EventWatcherはfsnotifyのWatcherをそのまま利用したもの 21 https://github.com/gohugoio/hugo/blob/master/watcher/filenotify/filenotify.go

Slide 22

Slide 22 text

© DMM fsnotifyとは? ➢ Goのファイルシステムのイベントを取得するパッケージ ○ ファイル・ディレクトリの操作情報を取得できる ➢ OSの機能を活用する ○ ファイルの変更、作成、削除の際に発生するイベントをOSから受信 22 https://github.com/fsnotify/fsnotify

Slide 23

Slide 23 text

© DMM fsnotifyとは? ➢ 複数のプラットフォームに対応している 23 https://github.com/fsnotify/fsnotify/blob/main/README.md

Slide 24

Slide 24 text

© DMM Linuxでのイベント取得 ➢ inotifyインスタンスと通信するファイルディスクリプタを取得 ○ OSのinotify APIの機能を利用 ➢ inotifyインスタンスを監視することでファイルの変更を検知 24 ファイルシステムを監視するための機能 https://github.com/fsnotify/fsnotify/blob/main/backend_inotify.go

Slide 25

Slide 25 text

© DMM ファイルディスクリプタとは? ➢ リソースのアクセスの際にOSから割り振られる番号(整数値) ○ アクセスする対象を識別する ■ ファイルだけではなく、標準入出力などのその他のリソースも扱う ○ アクセスの終了後は割り振った番号は解放される 25 ファイルディスクリプタを割 り当て

Slide 26

Slide 26 text

© DMM 監視対象の設定 ➢ ファイルディスクリプタからinotifyを読み込む場合、 全てのファイルの変更を取得してしまう →指定したパス直下のファイルの変更のみを取得する  ウォッチディスクリプタを生成 ウォッチディスクリプタからinotifyのイベントを取得する 26 https://github.com/fsnotify/fsnotify/blob/main/backend_inotify.go

Slide 27

Slide 27 text

© DMM 変更検知の流れ ➢ inotifyインスタンスを監視して変更を検知 27 Watcher イベント通知 送信 inotifyイベント 監視

Slide 28

Slide 28 text

© DMM 変更検知の流れ ➢ inotifyからイベントを取得するまで停止 28 Watcher イベント通知 送信 inotifyイベント 監視 ブロック

Slide 29

Slide 29 text

© DMM Watcher 変更検知の流れ 29 イベント通知 送信 inotifyイベント 監視 fsnotify.Write unix.IN_MODIFY ➢ inotifyのイベントを取得すると通知を送信

Slide 30

Slide 30 text

© DMM EventWatcherまとめ ➢ fsnotifyのWatcherを利用している ➢ OS自体の機能を活用してファイル変更のイベントを受信する 30

Slide 31

Slide 31 text

© DMM PollingWatcher ➢ 一定の周期でコードに変更が加えられているかチェックする ➢ 関数名や入出力の形式はfsnotifyのWatcherを踏襲している 31 https://github.com/gohugoio/hugo/blob/ master/watcher/filenotify/filenotify.go

Slide 32

Slide 32 text

© DMM Pollingを実行する周期の計測 ➢ pollingを実行する周期の計測にはTickerを利用 32 指定したintervalが経過するとチャネルに メッセージを送信する https://github.com/gohugoio/hugo/blob/master/watcher/filenotify/poller.go

Slide 33

Slide 33 text

© DMM Pollingを実行する周期の計測 ※Airで設定されるpolling interval ➢ デフォルト値は最小値である500msに設定されている ➢ 設定ファイルから変更が可能 33 https://github.com/air-verse/air/blob/master/runner/ watcher.go

Slide 34

Slide 34 text

© DMM Pollingを実行する周期の計測 ➢ Tickerからメッセージが送られるとファイルチェックが実行される ○ チェックが完了すると次のメッセージが送られるまで待機 34 待機 Ticker チャネル Watcherのgoroutine 変更チェック tickerのgoroutine 一定周期で メッセージを送信

Slide 35

Slide 35 text

© DMM PollingWatcherの監視対象 ➢ ファイル・ディレクトリのメタ情報を監視して変更を確認する 35 Watcher 最終変更時間 ファイルサイズ

Slide 36

Slide 36 text

© DMM Watcherの監視対象 変更チェックではファイル・ディレクトリのメタ情報を監視している 36 Watcher 最終変更時間 2025-09-17 19:00:00→2025-09-17 19:00:10 ファイルサイズ 500B→510B fsnotify.Write

Slide 37

Slide 37 text

© DMM Watcherの監視対象 変更チェックではファイル・ディレクトリのメタ情報を監視している 37 Watcher 最終変更時間 2025-09-17 19:00:00→2025-09-17 19:00:10 ファイルサイズ 500B→510B fsnotify.Write 前のpolling時点の 情報は変数で保持

Slide 38

Slide 38 text

© DMM PollingWatcherまとめ ➢ 一定周期でファイル変更を監視している ➢ ファイルの最終変更時間とサイズから変更を検知する 38

Slide 39

Slide 39 text

© DMM まとめ ➢ Airはコードの変更を検知することで最新のコードを反映している ➢ コードの変更検知にはhugo,fsnotifyが大きく関わっている ➢ 変更を検知するWatcherは二種類存在する ○ EventWatcher ■ OS自体のイベントを取得して変更を検知する ■ Airではこちらがデフォルトの選択肢 ○ PollingWatcher ■ 一定周期でファイルをチェックして変更を検知する 39

Slide 40

Slide 40 text

© DMM ご清聴ありがとうございました