返回 handle_call 值时在 case_clause 中抛出错误
Throw error in case_clause when returning handle_call value
我想要 handle_call \ 3 到 return 我一个以下形式的元组 {message, timestamp, integer} 然后在 case 子句中,它在我应该的时候给我一个错误通过与该响应对应的分支进入。
附上例子
execute(Method, Url, Headers, Body, PoolId) ->
BeforeGetConn = erlang:now(),
TimeStartBusy = undefined,
PosBusy = undefined,
TimeStartBusyAfterWait = undefined,
PosBusyAfterWait = undefined,
TimeInWaiting = undefined,
PosWaiting = undefined,
ShouldContinue =
case gen_server:call(?MODULE, {get_conn, PoolId, self(), BeforeGetConn}) of
proceed -> ok;
{wait, Ref, PosWaiting} ->
...
%Throw error in the following line
{proceed, TimeStartBusy, PosBusy} -> {ok, TimeStartBusy, PosBusy};
unknown_pool -> ...
end,
case ShouldContinue of
{ok, TimeStartBusy, PosBusy} ->
execute_process(...);
...
end.
handle_call({get_conn, PoolId, Caller, Time}, _From, #state{pools = Pools} = State) ->
case proplists:get_value(PoolId, Pools) of
undefined ->
...
Pool ->
case is_busy_full(Pool) of
false ->
Pool2 = add_to_busy({Caller}, Pool),
TimeStartBusy = os:timestamp(),
PosBusy = queue:len(Pool2#pool.busy),
{reply,
{proceed, TimeStartBusy, PosBusy},
State#state{pools = [{PoolId, Pool2} |
proplists:delete(PoolId, Pools)]}};
true ->
...
end
end;
我在控制台上看到的错误如下:
exit with reason:
{[{reason,{case_clause,{proceed,{1614,588434,663546},1}}}
谢谢
已编辑代码:
ShouldContinue =
case gen_server:call(?MODULE, {get_conn, PoolId, self(), BeforeGetConn}) of
proceed -> ok;
{wait, Ref, PosWaiting} ->
receive
{proceed, Ref, TimeStartBusyAfterWait, PosBusyAfterWait, TimeInWaiting} ->
TimeStartBusy = undefined,
PosBusy = undefined,
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait}
after ?CONF_BACKEND_HTTP_TIMEOUT ->
ok
end;
{proceed, TimeStartBusy, PosBusy} ->
PosWaiting = undefined,
TimeStartBusyAfterWait = undefined,
PosBusyAfterWait = undefined,
TimeInWaiting = undefined,
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait};
unknown_pool -> unknown_pool
end,
case ShouldContinue of
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait} ->
execute_process(BeforeGetConn, Url, Headers, Body, Method, PoolId, TimeStartBusy, PosBusy, TimeStartBusyAfterWait, PosBusyAfterWait, PosWaiting, TimeInWaiting);
ok ->
execute_process(BeforeGetConn, Url, Headers, Body, Method, PoolId, undefined, undefined, undefined, undefined, undefined, undefined);
unknown_pool ->
...
end.
出现这种情况是因为你在函数的开头将TimeStartBusy
和PosBusy
设置为undefined
,所以case子句{proceed, TimeStartBusy, PosBusy}
只能匹配元组{proceed, undefined, undefined}
。实际值为{proceed,{1614,588434,663546},1}
,所以不匹配
与大多数其他语言不同,Erlang 变量是单一赋值的:一旦设置了变量的值,就无法更改它,即使在 case 子句中的模式匹配中也是如此。要执行您想要的操作,只需删除 case 表达式之前将变量设置为 undefined
的行。这样,变量就会在比赛期间分配。
我想要 handle_call \ 3 到 return 我一个以下形式的元组 {message, timestamp, integer} 然后在 case 子句中,它在我应该的时候给我一个错误通过与该响应对应的分支进入。
附上例子
execute(Method, Url, Headers, Body, PoolId) ->
BeforeGetConn = erlang:now(),
TimeStartBusy = undefined,
PosBusy = undefined,
TimeStartBusyAfterWait = undefined,
PosBusyAfterWait = undefined,
TimeInWaiting = undefined,
PosWaiting = undefined,
ShouldContinue =
case gen_server:call(?MODULE, {get_conn, PoolId, self(), BeforeGetConn}) of
proceed -> ok;
{wait, Ref, PosWaiting} ->
...
%Throw error in the following line
{proceed, TimeStartBusy, PosBusy} -> {ok, TimeStartBusy, PosBusy};
unknown_pool -> ...
end,
case ShouldContinue of
{ok, TimeStartBusy, PosBusy} ->
execute_process(...);
...
end.
handle_call({get_conn, PoolId, Caller, Time}, _From, #state{pools = Pools} = State) ->
case proplists:get_value(PoolId, Pools) of
undefined ->
...
Pool ->
case is_busy_full(Pool) of
false ->
Pool2 = add_to_busy({Caller}, Pool),
TimeStartBusy = os:timestamp(),
PosBusy = queue:len(Pool2#pool.busy),
{reply,
{proceed, TimeStartBusy, PosBusy},
State#state{pools = [{PoolId, Pool2} |
proplists:delete(PoolId, Pools)]}};
true ->
...
end
end;
我在控制台上看到的错误如下:
exit with reason: {[{reason,{case_clause,{proceed,{1614,588434,663546},1}}}
谢谢
已编辑代码:
ShouldContinue =
case gen_server:call(?MODULE, {get_conn, PoolId, self(), BeforeGetConn}) of
proceed -> ok;
{wait, Ref, PosWaiting} ->
receive
{proceed, Ref, TimeStartBusyAfterWait, PosBusyAfterWait, TimeInWaiting} ->
TimeStartBusy = undefined,
PosBusy = undefined,
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait}
after ?CONF_BACKEND_HTTP_TIMEOUT ->
ok
end;
{proceed, TimeStartBusy, PosBusy} ->
PosWaiting = undefined,
TimeStartBusyAfterWait = undefined,
PosBusyAfterWait = undefined,
TimeInWaiting = undefined,
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait};
unknown_pool -> unknown_pool
end,
case ShouldContinue of
{ok, TimeStartBusy, PosBusy, TimeInWaiting, PosWaiting, TimeStartBusyAfterWait, PosBusyAfterWait} ->
execute_process(BeforeGetConn, Url, Headers, Body, Method, PoolId, TimeStartBusy, PosBusy, TimeStartBusyAfterWait, PosBusyAfterWait, PosWaiting, TimeInWaiting);
ok ->
execute_process(BeforeGetConn, Url, Headers, Body, Method, PoolId, undefined, undefined, undefined, undefined, undefined, undefined);
unknown_pool ->
...
end.
出现这种情况是因为你在函数的开头将TimeStartBusy
和PosBusy
设置为undefined
,所以case子句{proceed, TimeStartBusy, PosBusy}
只能匹配元组{proceed, undefined, undefined}
。实际值为{proceed,{1614,588434,663546},1}
,所以不匹配
与大多数其他语言不同,Erlang 变量是单一赋值的:一旦设置了变量的值,就无法更改它,即使在 case 子句中的模式匹配中也是如此。要执行您想要的操作,只需删除 case 表达式之前将变量设置为 undefined
的行。这样,变量就会在比赛期间分配。