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...
おわり
of 16

Poolboy

Introducing Poolboy at Riak Source Code Reading.
Published on: Mar 4, 2016
Published in: Technology      
Source: www.slideshare.net


Transcripts - Poolboy

  • 1. Poolboy Erlang入門
  • 2. お前誰よ• 村岡友介• @jbking• Python, JS with TypedArray• OTP使いこなしたい• Emacs久しぶりにインストール
  • 3. ワーカープール 使ってますよね?• pg_pool• ThreadPoolExecutor• MPM worker/prefork
  • 4. なぜワーカープールを 使いたいか• 重い初期化処理を何回もやりたくない • 初期化済みですぐ結果を返したい• リソースの同時使用を制限したい
  • 5. Poolboy 2a03513
  • 6. Usage プール名 (atom() as node())squery(PoolName, Sql) -> poolboy:transaction(PoolName, fun(Worker) -> gen_server:call(Worker, {squery, Sql}) end). ワーカープロセス (pid())gen_serverの下でワーカープロセスと 通信する
  • 7. ワーカー定義• -behaviour(gen_server).• -behaviour(poolboy_worker). • start_link/1 単なるgen_serverだよ!
  • 8. Internal
  • 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. 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. 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. 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. 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. Worker may crash
  • 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. おわり

Related Documents