fix(mnesia): per-slot volumes hint and harden verification lookup.
Avoid shared Mnesia dir across replicas; make get_or_create_token and CT verify_user resilient to brief cross-node lag. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,17 +34,19 @@ verify_token(Token) ->
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Возвращает существующий токен пользователя или создаёт новый.
|
||||
%%% Допускает несколько токенов на user_id (register + повторные вызовы).
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-spec get_or_create_token(UserId :: binary()) ->
|
||||
{ok, Token :: binary(), ExpiresAt :: calendar:datetime()} | {error, not_found}.
|
||||
get_or_create_token(UserId) ->
|
||||
case mnesia:dirty_match_object(#verification{user_id = UserId, _ = '_'}) of
|
||||
[V] -> {ok, V#verification.token, V#verification.expires_at};
|
||||
[] ->
|
||||
case core_user:get_by_id(UserId) of
|
||||
{ok, _} -> create_token(UserId);
|
||||
Error -> Error
|
||||
case find_token(UserId) of
|
||||
{ok, Token, ExpiresAt} ->
|
||||
{ok, Token, ExpiresAt};
|
||||
not_found ->
|
||||
case user_exists(UserId) of
|
||||
true -> create_token(UserId);
|
||||
false -> {error, not_found}
|
||||
end
|
||||
end.
|
||||
|
||||
@@ -55,4 +57,24 @@ get_or_create_token(UserId) ->
|
||||
-spec delete_token(Token :: binary()) -> ok.
|
||||
delete_token(Token) ->
|
||||
mnesia:dirty_delete(verification, Token),
|
||||
ok.
|
||||
ok.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
find_token(UserId) ->
|
||||
case mnesia:dirty_match_object(#verification{user_id = UserId, _ = '_'}) of
|
||||
[#verification{token = Token, expires_at = ExpiresAt} | _] ->
|
||||
{ok, Token, ExpiresAt};
|
||||
[] ->
|
||||
not_found
|
||||
end.
|
||||
|
||||
%% dirty_read first; transactional read as fallback for cluster replica lag.
|
||||
user_exists(UserId) ->
|
||||
case core_user:get_by_id(UserId) of
|
||||
{ok, _} -> true;
|
||||
{error, not_found} ->
|
||||
case mnesia:transaction(fun() -> mnesia:read(user, UserId) end) of
|
||||
{atomic, [_ | _]} -> true;
|
||||
_ -> false
|
||||
end
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user