名前 | スコープ |
---|---|
BIF | ローカル |
global | グローバル |
gproc | ローカル/グローバル |
名前 | スコープ |
---|---|
pg2 | グローバル |
gproc | ローカル/グローバル |
riak_pg | グローバル |
1> net_kernel:start([node1, shortnames]).
{ok,<0.35.0>}
(node1@localhost)2> net_kernel:connect_node(node2@localhost).
true
(node1@localhost)3> net_kernel:connect_node(node3@localhost).
true
(node1@localhost)4> nodes().
[node2@localhost,node3@localhost]
(node1@localhost)5> pg2:create(group).
ok
(node1@localhost)6> pg2:get_members(group).
[]
(node1@localhost)7> pg2:join(group, self()).
ok
(node1@localhost)8> pg2:get_members(group).
[<0.33.0>]
(node1@localhost)9> pg2:get_members(group).
[<0.33.0>,<7243.33.0>,<7281.33.0>]
(node1@localhost)10> pg2:leave(group, self()).
ok
(node1@localhost)11> pg2:get_members(group).
[<7243.33.0>,<7281.33.0>]
(node1@localhost)12> pg2:get_members(group).
[]
1> net_kernel:start([node2, shortnames]).
{ok,<0.35.0>}
(node2@localhost)2> nodes().
[node1@localhost,node3@localhost]
(node2@localhost)3> pg2:get_members(group).
{error,{no_such_group,group}}
(node2@localhost)4> pg2:join(group, self()).
ok
(node2@localhost)5> pg2:get_members(group).
[<7280.33.0>,<0.33.0>]
(node2@localhost)6> pg2:leave(group, self()).
ok
(node2@localhost)7> pg2:get_members(group).
[<7281.33.0>]
(node2@localhost)8> pg2:get_members(group).
[]
1> net_kernel:start([node3, shortnames]).
{ok,<0.35.0>}
(node3@localhost)2> nodes().
[node1@localhost,node2@localhost]
(node3@localhost)3> pg2:get_members(group).
{error,{no_such_group,group}}
(node3@localhost)4> pg2:join(group, self()).
ok
(node3@localhost)5> pg2:get_members(group).
[<7280.33.0>,<7281.33.0>,<0.33.0>]
(node3@localhost)6> pg2:leave(group, self()).
ok
(node3@localhost)7> pg2:get_members(group).
[]
(node3@localhost)8> pg2:get_members(group).
[]
1> net_kernel:start([node1, shortnames]).
{ok,<0.35.0>}
(node1@localhost)2> net_kernel:connect_node(node2@localhost).
true
(node1@localhost)3> net_kernel:connect_node(node3@localhost).
true
(node1@localhost)4> nodes().
[node2@localhost,node3@localhost]
(node1@localhost)5> application:ensure_all_started(gproc).
{ok,[gproc]}
(node1@localhost)6> gproc_dist:start_link(all).
{ok,<0.62.0>}
(node1@localhost)7> gproc:lookup_pids({p, g, group}).
[]
(node1@localhost)8> gproc:reg({p, g, group}).
true
(node1@localhost)9> gproc:lookup_pids({p, g, group}).
[<0.33.0>]
(node1@localhost)10> gproc:lookup_pids({p, g, group}).
[<0.33.0>,<7243.33.0>,<7281.33.0>]
(node1@localhost)11> gproc:unreg({p, g, group}).
true
(node1@localhost)12> gproc:lookup_pids({p, g, group}).
[<7243.33.0>,<7281.33.0>]
(node1@localhost)13> gproc:lookup_pids({p, g, group}).
[]
1> net_kernel:start([node2, shortnames]).
{ok,<0.35.0>}
(node2@localhost)2> nodes().
[node1@localhost,node3@localhost]
(node2@localhost)3> application:ensure_all_started(gproc).
{ok,[gproc]}
(node2@localhost)4> gproc_dist:start_link(all).
{ok,<0.62.0>}
(node2@localhost)5> gproc:reg({p, g, group}).
true
(node2@localhost)6> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<0.33.0>]
(node2@localhost)7> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<0.33.0>,<7281.33.0>]
(node2@localhost)8> gproc:unreg({p, g, group}).
true
(node2@localhost)9> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<0.33.0>,<7281.33.0>]
(node2@localhost)10> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<0.33.0>,<7281.33.0>]
1> net_kernel:start([node3, shortnames]).
{ok,<0.35.0>}
(node3@localhost)2> nodes().
[node1@localhost,node2@localhost]
(node3@localhost)3> application:ensure_all_started(gproc).
{ok,[gproc]}
(node3@localhost)4> gproc_dist:start_link(all).
{ok,<0.62.0>}
(node3@localhost)5> gproc:reg({p, g, group}).
true
(node3@localhost)6> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<7281.33.0>,<0.33.0>]
(node3@localhost)7> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<7281.33.0>,<0.33.0>]
(node3@localhost)8> gproc:unreg({p, g, group}).
true
(node3@localhost)9> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<7281.33.0>,<0.33.0>]
(node3@localhost)10> gproc:lookup_pids({p, g, group}).
[<7280.33.0>,<7281.33.0>,<0.33.0>]
{error,{riak_core,{{shutdown,{failed_to_start_child,riak_core_ring_manager,
{bad_return_value,{error,enoent}}}},
{riak_core_app,start,[normal,[]]}}}}
同じグループに複数回、参加できてしまう。
A process can join a group several times;
- http://erlang.org/doc/man/pg2.html#join-2
- http://erlang.org/pipermail/erlang-questions/2010-April/050992.html
グループの状態を更新するときに、グローバルなロックが掛かる。
- http://github.com/erlang/otp/blob/maint/lib/kernel/src/pg2.erl#L79
- http://github.com/erlang/otp/blob/maint/lib/kernel/src/pg2.erl#L79
動的なグループの状態の更新において、gen_leader
の実装に起因するネットスプリットの問題がある。
- http://en.wikipedia.org/wiki/Netsplit
- http://en.wikipedia.org/wiki/Two_Generals%27_Problem
- http://en.wikipedia.org/wiki/Byzantine_fault_tolerance
- http://erlang.org/pipermail/erlang-questions/2012-July/067749.html
- http://christophermeiklejohn.com/erlang/2013/06/05/erlang-gproc-failure-semantics.html#comment-922065906
- 従来のモジュールの問題点を解消することを目標としている。
- まだ
Work in progress, not for production use.
な状態。 - 内部的に
riak_dt
とriak_core
を利用している。 - 全面的に
gen_fsm
を利用している。
- http://christophermeiklejohn.com/erlang/2013/06/03/erlang-pg2-failure-semantics.html
- http://speakerdeck.com/cmeiklejohn/riak-pg-distributed-process-groups-on-dynamo-style-distributed-storage
- http://christophermeiklejohn.com/erlang/riak/crdt/2013/06/24/introducing-riak-pg-distributed-process-groups-for-erlang.html