追記 2015/11/08 [Elixir]1worker、1portでリクエストを待ってHTTPのリクエストをProxyする で解消済 最近、簡単なHTTP Proxyを書いてみています。Elixir/Erlangの多プロセスで動作する点を利用して、軽量なproxyとして動作できるのかなー?というところがあってです。 https://github.com/KazuCocoa/http_proxy 以下のような感じでportを指定したら、そのportに対してどんなパスでアクセスしたかで接続先を制御できる感じにしています。 Plug や Cowboy を結局は使っています。Supervisorのworkerとしてプロセスは起動するようにもしています。 この動作確認の中で、ElixirのSupervisorで複数のPlugを持つ同一モジュールを動かそうとしたらPIDの競合でエラーがでたのでメモ。少し調べてみると、それはPlugが Plug.Adapters.Cowboy.httpや Plug.Adapters.Cowboy.https をSupervisorで起動するときに :name で __MODULE__ を指定しているのが原因な気がしています。 というのも、例えばSupervisorで呼ばれたときにまず起動するここらへんで使われる、start_link で最初に呼ばれるところで ref: を与えたり、 workerで与える :id を変えても変化なかったためです。ここな感じ。More
Tag Archives: program
[Elixir]GenServerのcallとhandle_callにおける:nameによる指定
GenServer.start_link __MODULE__, default, [name: __MODULE__] で name を指定することの必要性に関してメモ。 以下の通り、Sample.neko を読んだ時、 __MODULE__ にメッセージが送られてGenServerのコールバックであるhandle_call にメッセージが送られる。そのパターンマッチで処理される handle_call が決定、実際にプロセスで処理される。という一連の処理を作るために、 start_link では名前をちゃんと与えることが必要。そうでなければ、process idを直接指定しなくてはいけない。(それはあまり現実的ではない..) 関連した修正はこちら https://github.com/KazuCocoa/my_bot_ex/commit/b9be93de02e47b97a2a2e93dcbb46104ddb47004More
[Elixir][Swift]ElixirやSwiftのprotocolなどの話
たまたま見つけて。 Comparing protocols and extensions in Swift and Elixir http://blog.plataformatec.com.br/2014/06/comparing-protocols-and-extensions-in-swift-and-elixir/ ElixirはClojureに影響されているのですね。protocol周辺の使い道。 パッと、 defimpl の対象となるタイプを思い出せなかったので以下にURLを一応。 http://elixir-lang.org/docs/stable/elixir/Kernel.html#defprotocol/2 こんな感じ。 defimpl の 第一引数のタイプ によって、どのタイプに対する実装かを示しています。 Swiftは、記事のものは古いので省略。も少しあとで。More
[Java]最大値の反転で負の数値になってた(初歩的なミス…)
Javaの、基本的なところで見逃してしまった不具合を、自戒を込めてメモ… キャストの順序により、補数によって負の数値として扱われていたのか… long で宣言されていた time を計算で使っているので、括弧内の計算も long で計算されるとなんか脳内変換していた…テストする人として、見逃してはいけないような初歩的なミスだ… ※DateUtils使えば、とかの話は置いておいて… This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters import java.lang.Long; import java.lang.System; import…More
[Elixir]Post app reviews, get with simple_app_reporter_ex, to Slack
I implemented simple posting app reviews to slack with Elixir-Slack(version 0.2.0) and Reporter(version 0.2.5). Base implementation to handle post to slack with Elixir-Slack This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.…More
『Programming Phoenix』を読んでみた(まだドラフト版)
ElixirによるRoR実装と表現される、Phoenix Frameworkの作者による書籍『Programming Phoenix』を読んでみました。今はドラフト版ですが、こういうフレームワークの基本的な思想とか好きなのと、PhoenixはElixirのmacroを駆使しているという話をみて、気になって買って読んでみました。(Elixir、macroがほぼそのままLips形式の記述なのですが、そこも著者は気に入っているそう。) 以下ではElixir 1.1.0、Phoenix 1.0.3を対象としてます。 内容としては、簡単なサンプルを作りながらPhoenixの話、Ecto、Plug.Conn、Ecto.QueryなどのElixirの基礎要素の話がありました。テストの話なんかはまだ書きかけ。Phoenixの話ばかりと思ってたら、結構Elixirの周辺の機構の主要な要素をかいつまんでいて、良い意味でびっくりでした。 個人的には、 https://github.com/KazuCocoa/web_qa_vote で作っていたことがこの書籍読んだあとだったらもっとサクッとできたのかな、という感じでした。ある程度Elixirの文法わかって、簡単なWebアプリ作ったことがある人が、中身を理解するという段階で有用な書籍っぽい。 技術的なところは置いておいて、個人的に面白かったのは、所々でてくる、著者らによるコラムです。なんでこうしたか?というところに、どのような意図があってこうした、というのが散らばってます。 例えば、Phoenixの内部処理ではAtom keyを使うけれど、外部(開発者)はString keyでパラメータを書く。これは、データの安全性への考慮を含めているから、というような。Phonenixの web ディレクトリと lib ディレクトリの役割の違いなど。あと、HTMLのtemplateの処理がPhoenixではなぜ早いか?というところに対しては、Phonenixは、templateをStringではなくlinked listsとして扱っているから、そのぶん性能的な改善が見られる、らしい。 以下、書籍のまとめとかではないけれど、個人的に派生して読んだり学んだことのメモ。 Phoenixのテンプレート的な話 Viewを生成するとき、以下の Phoneix.HTML.safe_to_string の関数を通して、 :safe 要素を持つTupleでViewのhtmlを表現したりしている。 https://github.com/phoenixframework/phoenix_html/blob/master/lib/phoenix_html.ex#L156 Dive to logic of authorization 認証機構の実装の話も扱っていたので、ついでにGuardianの中身も覗いてみました。結構似たことしているので、初見では読み悩んでいた箇所もスラスラ読めるようになっててびっくり。 例えば、sign_inした状態のsessionを作り出すときの話。Guardianを使う場合、以下のような処理を書いたりします。 この中で、 Guardian.Plug.sign_in/4 を覗いてみると以下のような処理をしています。 guardian/lib/guardian/plug.ex この中でパイプでつながっている set_* 系のものを見ていると、 Plug.Conn.* のPlugの機構の中で put_session とかしてて、いろいろ conn に Map.put して情報を付与していることがわかります。 つまるとこ、Guardianは conn の構造体にあるassignsやstateなんかのキーに値を追加していっているのですね。なるほど。ちなみに、 put_session は、 Plug.ConnのprivateのMapに独自の情報を追加していくのですね。…More
[Elixir]power_assert_exをex_parameterizedと組み合わせて使ってみた
Power AssertのElixir版を、 @ma2ge さんが作成されていたので、ex_parameterizedと合わせてみました。ex_parameterizedは、パラメータ化テストの記述を支援する、簡単なマクロです。 power_assert_ex https://github.com/ma2gedev/power_assert_ex ex_parametarized https://github.com/KazuCocoa/ex_parameterized やることは簡単。単に、 use ExUnit.Case を use PowerAssert に置き換えるだけでした。 ex_parameterized自体、単に test マクロを内部では使っているだけなので、特に変なAST操作は行っていません。なので、問題なく表示されました。すごい。 以下は、ex_parameterizedのテストをわざと失敗させた時の出力結果です。 まだ色々と制限もありますし、ExUnitの結果自体そんなに読みにくいテスト結果なわけではありません。ただ、なんだかんだでテスト結果を観察することが楽になりますので、良いなーと思いました。More
[Elixir]Plugを使ってたときにPhoenixの1request-1processが気になったので追ってみた
ちょっとしたHTTPの処理を受けるサーバを Plug を使って実装してようとしたら、 Plug.Adapters.Cowboy.child_spec() をすることになりました。また、trotも少し処理を追ってみると同様なところに行き着く。 ふと作業している途中で、Phoenixだと、1 request – 1 processとなるendpointの処理は結局はどこが処理してそうなっているのだろう、という疑問がわいたので、 すべきことを横に置いて さかのぼってみました。 過去、似たようなところとして以下のようなものを追っていました。 [Elixir]Phoenix.Router付近やendpointを追ってみる [Elixir]PhoenixのSupervisorのstrategy 開始地点 ひとまず、雑に Plug.Adapters.Cowboy で検索してみました。これは、Elixirの機構を使っているなら、最終的に同様にPlugにいくだろう、とのことから。 すると、Plug.Adapters.Cowboy.Handler なんかが検索に引っかかります。 この中から、 Phoenix.Endpoint.CowboyHandler の child_spec の中で使われているのを見つけました。この child_spec は、Subversion Treeの中で呼ばれます。 同様に、このHandlerをみてみると、この行にて、 が呼ばれていることがわかります。つまり、Phoenixのendpointの処理は、最終的にはPlugを使い、Cowboyへと向かっているのですね。 なるほど。 Subversion Treeを遡る もう少し、今度はSubversionがどのように流れているのかを追ってみました。つまり、 Phoenix.Endpoint.CowboyHandler がSubversion Treeの中で呼ばれるところを探す、です。 検索してみると、Phoenix.Endpoint.Serverで、 として定義され、この@handler が同じファイル内の initの箇所で呼ばれています。 じゃあ、このPhoenix.Endpoint.ServerをどのSubervionが呼んでいるのか?というと、Phoenix.Endpoint.Adapterで呼ばれていました。 もう少しさかのぼると、 Phoenix.Endpoint.Adapter は Phoenix.Endpoint の def server()内で stat_linkされるようです。この server() は、同じファイルの __using__ で呼ばれているので、Phoenix.Endpoint…More
[Elixir]defmacroに2つの要素を持つTupleを与えるとき、例外的にTupleがそのままASTとして使われる
ex_parameterizedを修正していたときに遭遇した振る舞い。 以下の通り、簡単な defmacro でマクロを定義していたら、 Example.a(do: {1, 2}) のように、この場合だけ意図しない出力が得られました。 これ、 Example.a(do: {1, 2}) の出力として [do: {:{}, [line: 11], [1, 2]}] が得られないといけない、と思って 聞いてみた ら、これは以下の通り問題ないみたいですね。 http://elixir-lang.org/docs/master/elixir/Kernel.SpecialForms.html#quote/2 Quote literals Besides the tuple described above, Elixir has a few literals that when quoted return themselves. They are: つまるところ、この defmacro の中身の Example.a(do: {1, 2}) は、 {key, value} のtupleに該当するから [do: {1, 2}]…More
[Elixir]Parameterized Test with macros
hex.pmになかったのと、macroの練習がてら parameterized test の記述をサポートするmacroを書いてみました。 すごく簡単なminimamなmacroです 🙂 https://hex.pm/packages/ex_parameterized https://github.com/KazuCocoa/ex_parameterized こんな感じで test_with_params を接頭辞として使います。 内部では、 test をそのまま使っているのと、 line numberをそれぞれのテストケースで使っているので、テスト失敗した時でも何行目のパラメータで失敗したのかわかるようになってます。 Javaだと、@RunWith(Parameterized.class) や @RunWith(Theories.class) を使って書くやり方が推奨されているやつですね。(過去のBlog) RubyだとRSpecのモジュールやminitestとかでも実装されていますね。More