#erlang
#erlang
Вопрос:
Я хочу, чтобы handle_call 3 возвращал мне кортеж следующего вида {сообщение, временная метка, целое число}, а затем в предложении 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;
Ошибка, которую я вижу на консоли, заключается в следующем:
завершите с указанием причины: {[{причина,{case_clause,{продолжить,{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.
Комментарии:
1. Пожалуйста, не создавайте лишней работы для других людей, вандализируя свои посты. Публикуя в сети Stack Exchange, вы предоставляете Stack Exchange не подлежащее отзыву право в соответствии с лицензией CC BY-SA 4.0 на распространение этого контента (т. Е. Независимо от ваших будущих решений). Согласно политике обмена стеками, распространяется версия post, не подвергшаяся вандализму. Таким образом, любой вандализм будет отменен. Если вы хотите узнать больше об удалении записи, пожалуйста, смотрите: Как работает удаление?
Ответ №1:
Это происходит потому, что вы устанавливаете TimeStartBusy
и PosBusy
undefined
в начале функции, поэтому предложение case {proceed, TimeStartBusy, PosBusy}
может соответствовать только кортежу {proceed, undefined, undefined}
. Фактическое значение равно {proceed,{1614,588434,663546},1}
, поэтому оно не совпадает.
В отличие от большинства других языков, переменные Erlang имеют одно назначение: после того, как вы установили значение переменной, его невозможно изменить, даже при сопоставлении с шаблоном, как в предложении case . Чтобы сделать то, что вы хотите, просто удалите строки, которые устанавливают переменные undefined
перед выражением case . Таким образом, переменные присваиваются во время сопоставления.
Комментарии:
1. Хорошо, но если я отменю назначение переменных, теперь он выдает эту ошибку:
'PosBusy' insecure in 'case'.
для каждой переменной, которая ранее была инициализирована как неопределенная2. Это происходит потому
PosBusy
, что присваивается в некоторых, но не во всех предложениях case . Следовательно, вы не можете использовать его после выражения case, поскольку оно может иметь или не иметь значения в этот момент.3. Теперь я добавил это в код (вы можете увидеть это во фрагменте кода), но все еще показываю ту же ошибку
4. Здесь аналогичная проблема:
PosBusy
сопоставляется с в предложении case , что означает, что оно должно быть назначено либо во всех путях кода, ведущих к этой точке, либо ни в одном из них. Возможно, было бы проще переместить второе выражение case в отдельную функцию — это позволит вам начать с «чистого листа», причем единственными определенными переменными являются те, которые передаются в качестве аргументов функции.