@matsumotory さんが ngx_mruby の v2-dev を開発中ということで、社のプロダクションに入れていくため新機能について調べたのでまとめる。
ngx_mrubyのv2-devブランチ、ノンブロックsleepとか実装済みなので、ノンブロックなメソッドと組み合わせて自前イベントループとか作れると思うので是非お試しください。さらにはRubyのスクリプトはfiberで実行されるように大きく変更したので何か問題があればissueにして頂けるとこれまた幸いです。
— 松本 亮介 / まつもとりー (@matsumotory) 2018年5月1日
機能としては、大きく以下のような追加になるとのこと。
return
の実装Nginx::Async.sleep
の実装- ノンブロッキングなhttpクライアントの実装(comming soon)
本エントリでは、それぞれの機能について見ていく。
return
の実装
これまで以下のようなコードは、初見だと意図しない挙動をする。
Nginx.echo "OK"
Nginx.return Nginx::DECLINED # ここでプログラムからreturnすると思いがち
Nginx.echo "NG"
# => "OKNG"
対応方法として、以下のようにLambdaで記述していた。
Nginx.return -> do
Nginx.echo "OK"
return Nginx::DECLINED
Nginx.echo "NG"
end
# => "OK"
v2からは以下のように記述可能
Nginx.echo "OK"
Nginx.return Nginx::DECLINED
return
Nginx.echo "NG"
# => "OK"
Nginx::Async.sleep
の実装
ノンブロッキングsleepの実装。1 nginx workerプロセスの動きを説明する。
これまでのngx_mruby
v2のngx_mruby
このように、処理ができる。 つまり、何か重い処理やや外部コマンドを実行するようなときにsleepさせて別の処理を実行するということが可能となる。
実際の実装や動作については、以下が非常に参考になる。
ノンブロッキングについては、以下の記事が非常に参考になった。
ノンブロッキングなhttpクライアントの実装(comming soon)
社内で @matsumotory さんから聞いた情報によると、ノンブロッキングなhttpクライアントの機能が実装されるとのこと。
これは、非常に便利で極力な機能で、例としてはnginxの挙動を外部APIの実行結果を元に変更するようなことをしたい場合に、これまでhttpリクエストの処理中はブロッキングされていたがv2から実装される機能を利用するとその間は別の処理を行うことができるため全体的に高速に動作するようになる。
私が担当するプロダクトについては、nginxの挙動を変更するためのパラメータをMySQLのデータベースからRedisにキャッシュしつつ取得している。その為、nginx側にビジネスロジックを持っていてそれが変更になることによって同様の変更をする必要がある。ビジネスロジックをもつhttpベースのAPIが存在するため、そちらから取得すればビジネスロジックの変更に強いし今回のノンブロッキング化が入ることで実現の可能性がある。
これと関連して、mruby-mysqlやmruby-redisなどブロッキングが発生する処理についてもノンブロッキングなメソッドを新たに実装することによって、ngx_mrubyとの組み合わせで同様な効果が得られるため今後の進化の幅が広がったと思える。