[Elixir]Elixirで簡単なHTTP Proxyを書いているときに出会ったエラーのメモ

追記 2015/11/08

[Elixir]1worker、1portでリクエストを待ってHTTPのリクエストをProxyする で解消済


最近、簡単なHTTP Proxyを書いてみています。Elixir/Erlangの多プロセスで動作する点を利用して、軽量なproxyとして動作できるのかなー?というところがあってです。

https://github.com/KazuCocoa/http_proxy

以下のような感じでportを指定したら、そのportに対してどんなパスでアクセスしたかで接続先を制御できる感じにしています。

use Mix.Config

config :http_proxy,
  proxy: %{port: 4000,
           default_to: "http://google.com",
           path: [
               %{from: "", to: "http://yahoo.com"},
               %{from: "neko", to: "http://yahoo.co.jp"}
             ]
           }

PlugCowboy を結局は使っています。Supervisorのworkerとしてプロセスは起動するようにもしています。

この動作確認の中で、ElixirのSupervisorで複数のPlugを持つ同一モジュールを動かそうとしたらPIDの競合でエラーがでたのでメモ。少し調べてみると、それはPlugが Plug.Adapters.Cowboy.httpPlug.Adapters.Cowboy.https をSupervisorで起動するときに :name__MODULE__ を指定しているのが原因な気がしています。

というのも、例えばSupervisorで呼ばれたときにまず起動するここらへんで使われる、start_link で最初に呼ばれるところで ref: を与えたり、

  def start_link(proxy) do
    {:ok, pid} = Plug.Adapters.Cowboy.http __MODULE__, [ref: proxy[:name]], port: proxy[:port].port

    IO.inspect pid
    {:ok, pid}
    # :timer.sleep(:infinity)
  end

workerで与える :id を変えても変化なかったためです。ここな感じ。

  def init(:ok) do
    import Supervisor.Spec

   children = [
     worker(HttpProxy, [[port: 4000, name: String.to_atom("HttpProxy1")]], [id: String.to_atom("HttpProxy1")]),
     worker(HttpProxy, [[port: 4001, name: String.to_atom("HttpProxy2")]], [id: String.to_atom("HttpProxy2")])
   ]

    supervise children, strategy: :one_for_one
  end
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s