Stuff Goes Bad:Erlang In Anger

Example: Initializing without guaranteeing connections

示例:没有保证连接的初始化

The following code attempts to guarantee a connection as part of the process’ state:

 下面代码试图保证进程在初始化过程中必然连接成功。

----------------------------------------------------------------------------------
1 init(Args) ->
2 Opts = parse_args(Args),
3 {ok, Port} = connect(Opts),
4 {ok, #state{sock=Port, opts=Opts}}.
5
6 [...]
7
8 handle_info(reconnect, S = #state{sock=undefined, opts=Opts}) ->
9 %% try reconnecting in a loop
10 case connect(Opts) of
11 {ok, New} -> {noreply, S#state{sock=New}};
12 _ -> self() ! reconnect, {noreply, S}
13 end;
----------------------------------------------------------------------------------
 Instead, consider rewriting it as:

 考虑重写如下:

----------------------------------------------------------------------------------
1 init(Args) ->
2 Opts = parse_args(Args),
3 %% you could try connecting here anyway, for a best
4%% effort thing, but be ready to not have a connection.
5 self() ! reconnect,
6{ok, #state{sock=undefined, opts=Opts}}.
7
8 [...]
9
10handle_info(reconnect, S = #state{sock=undefined, opts=Opts}) ->
11%% try reconnecting in a loop
12case connect(Opts) of
13{ok, New} -> {noreply, S#state{sock=New}};
14_ -> self() ! reconnect, {noreply, S}
15end;
----------------------------------------------------------------------------------
You now allow initializations with fewer guarantees: they went from the connection is available to the connection manager is available.

 重写后,用更少的操作来保证初始化的成功,因为他在初始化之后立即在handle_info中连接socket,并在不连接不成功后马上重连(对比于第一种情况的连接失败就不断重启进程明显好用多啦)。