Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Poolboy Erlang入門
お前誰よ• 村岡友介• @jbking• Python, JS with TypedArray• OTP使いこなしたい• Emacs久しぶりにインストール
ワーカープール     使ってますよね?• pg_pool• ThreadPoolExecutor• MPM worker/prefork
なぜワーカープールを   使いたいか• 重い初期化処理を何回もやりたくない • 初期化済みですぐ結果を返したい• リソースの同時使用を制限したい
Poolboy 2a03513
Usage                           プール名        (atom() as node())squery(PoolName, Sql) ->    poolboy:transaction(PoolName, fu...
ワーカー定義• -behaviour(gen_server).• -behaviour(poolboy_worker). • start_link/1      単なるgen_serverだよ!
Internal
Initialize% poolboy.erl:77start(PoolArgs, WorkerArgs) ->    start_pool(start, PoolArgs, WorkerArgs).% poolboy.erl:89start_...
Initialize            gen_server module            Callback module            -----------------            ---------------...
Transaction                      さっきのpoolboy:transaction/3% poolboy.erl:48           プールからワーカーを取り出してtransaction(Pool, Fun,...
Checkout% poolboy.erl:133handle_call({checkout, Block, Timeout}, {FromPid, _} = From, State) ->    #state{supervisor = Sup...
Checkin% poolboy.erl:119handle_cast({checkin, Pid}, State = #state{monitors = Monitors}) ->    case ets:lookup(Monitors, P...
Worker may crash
Monitor/Trap% poolboy.erl:180                 Monitorhandle_info({DOWN, Ref, _, _, _}, State) ->    case ets:match(State#s...
おわり
Upcoming SlideShare
Loading in …5
×

Poolboy

Introducing Poolboy at Riak Source Code Reading.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to comment

  • Be the first to like this

Poolboy

  1. 1. Poolboy Erlang入門
  2. 2. お前誰よ• 村岡友介• @jbking• Python, JS with TypedArray• OTP使いこなしたい• Emacs久しぶりにインストール
  3. 3. ワーカープール 使ってますよね?• pg_pool• ThreadPoolExecutor• MPM worker/prefork
  4. 4. なぜワーカープールを 使いたいか• 重い初期化処理を何回もやりたくない • 初期化済みですぐ結果を返したい• リソースの同時使用を制限したい
  5. 5. Poolboy 2a03513
  6. 6. Usage プール名 (atom() as node())squery(PoolName, Sql) -> poolboy:transaction(PoolName, fun(Worker) -> gen_server:call(Worker, {squery, Sql}) end). ワーカープロセス (pid())gen_serverの下でワーカープロセスと 通信する
  7. 7. ワーカー定義• -behaviour(gen_server).• -behaviour(poolboy_worker). • start_link/1 単なるgen_serverだよ!
  8. 8. Internal
  9. 9. Initialize% poolboy.erl:77start(PoolArgs, WorkerArgs) -> start_pool(start, PoolArgs, WorkerArgs).% poolboy.erl:89start_link(PoolArgs, WorkerArgs) -> start_pool(start_link, PoolArgs, WorkerArgs).% poolboy.erl:223 ワーカープール初期化start_pool(StartFun, PoolArgs, WorkerArgs) -> case proplists:get_value(name, PoolArgs) of undefined -> gen_server:StartFun(?MODULE, {PoolArgs, WorkerArgs}, []); Name -> gen_server:StartFun(Name, ?MODULE, {PoolArgs, WorkerArgs}, end.
  10. 10. Initialize gen_server module Callback module ----------------- --------------- gen_server:start_link -----> Module:init/1% poolboy.erl:91 ワーカープール初期化init({PoolArgs, WorkerArgs}) -> process_flag(trap_exit, true), Waiting = queue:new(), Monitors = ets:new(monitors, [private]), State構築 init(PoolArgs, WorkerArgs, #state{waiting = Waiting, monitors = Mon poolboyプール自身も gen_serverの下で動いている
  11. 11. Transaction さっきのpoolboy:transaction/3% poolboy.erl:48 プールからワーカーを取り出してtransaction(Pool, Fun, Timeout) -> Worker = poolboy:checkout(Pool, true, Timeout), try Fun(Worker) 実行して after ok = poolboy:checkin(Pool, Worker) end. 終わったらプールに戻す
  12. 12. Checkout% poolboy.erl:133handle_call({checkout, Block, Timeout}, {FromPid, _} = From, State) -> #state{supervisor = Sup, workers = Workers, monitors = Monitors, overflow = Overflow, max_overflow = MaxOverflow} = State, case queue:out(Workers) of {{value, Pid}, Left} -> プールからPidを取り出す Ref = erlang:monitor(process, FromPid), true = ets:insert(Monitors, {Pid, Ref}), {reply, Pid, State#state{workers = Left}}; {empty, Empty} when MaxOverflow > 0, Overflow < MaxOverflow -> ... プロセスをモニターに登録
  13. 13. Checkin% poolboy.erl:119handle_cast({checkin, Pid}, State = #state{monitors = Monitors}) -> case ets:lookup(Monitors, Pid) of [{Pid, Ref}] -> モニターから解除 true = erlang:demonitor(Ref), true = ets:delete(Monitors, Pid), NewState = handle_checkin(Pid, State), {noreply, NewState}; [] -> 待ちプロセスにワーカーを {noreply, State} end; 割り当てる
  14. 14. Worker may crash
  15. 15. Monitor/Trap% poolboy.erl:180 Monitorhandle_info({DOWN, Ref, _, _, _}, State) -> case ets:match(State#state.monitors, {$1, Ref}) of [[Pid]] -> ... [] -> ... end; Traphandle_info({EXIT, Pid, _Reason}, State) -> #state{supervisor = Sup, monitors = Monitors} = State, case ets:lookup(Monitors, Pid) of [{Pid, Ref}] -> ... [] -> ... end;
  16. 16. おわり

×