fix host_status

This commit is contained in:
anlicheng 2026-05-09 23:27:27 +08:00
parent 0dd6f9715a
commit fe46aff527

View File

@ -36,6 +36,9 @@
host_id :: integer(), host_id :: integer(),
%% %%
uuid :: binary(), uuid :: binary(),
%%
host_status :: integer(),
has_session = false :: boolean(), has_session = false :: boolean(),
%% %%
heartbeat_counter = 0 :: integer(), heartbeat_counter = 0 :: integer(),
@ -179,7 +182,7 @@ start_link(Name, UUID) when is_binary(UUID) ->
init([UUID]) -> init([UUID]) ->
ok = iot_log:set_metadata(), ok = iot_log:set_metadata(),
case iot_api_client:get_host_by_uuid(UUID) of case iot_api_client:get_host_by_uuid(UUID) of
{ok, #host_info{id = HostId, authorize_status = AuthorizeStatus}} -> {ok, #host_info{id = HostId, authorize_status = AuthorizeStatus, status = HostStatus}} ->
%% host_id注册别名, HostPid %% host_id注册别名, HostPid
AliasName = get_alias_name(HostId), AliasName = get_alias_name(HostId),
global:register_name(AliasName, self()), global:register_name(AliasName, self()),
@ -191,7 +194,7 @@ init([UUID]) ->
true -> ?STATE_ACTIVATED; true -> ?STATE_ACTIVATED;
false -> ?STATE_DENIED false -> ?STATE_DENIED
end, end,
{ok, StateName, #state{host_id = HostId, uuid = UUID, has_session = false}}; {ok, StateName, #state{host_id = HostId, uuid = UUID, host_status = HostStatus, has_session = false}};
undefined -> undefined ->
logger:warning("[iot_host] host uuid: ~p, load host info failed", [UUID]), logger:warning("[iot_host] host uuid: ~p, load host info failed", [UUID]),
ignore ignore
@ -309,24 +312,38 @@ handle_event(cast, {handle, {ping, Metrics}}, ?STATE_ACTIVATED, State = #state{u
{keep_state, State#state{metrics = Metrics}}; {keep_state, State#state{metrics = Metrics}};
%% %%
handle_event(cast, heartbeat, _, State = #state{uuid = UUID, heartbeat_counter = HeartbeatCounter}) -> handle_event(cast, heartbeat, _, State = #state{uuid = UUID, heartbeat_counter = HeartbeatCounter, host_status = HostStatus}) ->
maybe_mark_host_online(UUID), case maybe_mark_host_online(UUID, HostStatus) of
{keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1}}; keep_status ->
{keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1}};
{next_status, NStatus} ->
{keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1, host_status = NStatus}}
end;
%% UDP SSL channel host 线 %% UDP SSL channel host 线
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, channel_pid = ChannelPid}) when is_pid(ChannelPid) -> handle_event(info, {timeout, _, heartbeat_ticker}, _,
logger:warning("[iot_host] uuid: ~p, udp heartbeat lost but ssl channel is alive: ~p", [UUID, ChannelPid]), State = #state{uuid = UUID, heartbeat_counter = 0, host_status = HostStatus, channel_pid = ChannelPid}) when is_pid(ChannelPid) ->
maybe_mark_host_online(UUID),
erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker), erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker),
{keep_state, State#state{heartbeat_counter = 0}}; logger:warning("[iot_host] uuid: ~p, udp heartbeat lost but ssl channel is alive: ~p", [UUID, ChannelPid]),
case maybe_mark_host_online(UUID, HostStatus) of
keep_status ->
{keep_state, State#state{heartbeat_counter = 0}};
{next_status, NStatus} ->
{keep_state, State#state{heartbeat_counter = 0, host_status = NStatus}}
end;
%% UDP SSL channel线, %% UDP SSL channel线,
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0}) -> handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, host_status = HostStatus}) ->
logger:warning("[iot_host] uuid: ~p, heartbeat lost, devices will unknown", [UUID]), logger:warning("[iot_host] uuid: ~p, heartbeat lost, devices will unknown", [UUID]),
maybe_mark_host_offline(UUID),
erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker), erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker),
case maybe_mark_host_offline(UUID, HostStatus) of
keep_status ->
{keep_state, State#state{channel_pid = undefined, has_session = false, heartbeat_counter = 0}};
{next_status, NStatus} ->
{keep_state, State#state{channel_pid = undefined, host_status = NStatus, has_session = false, heartbeat_counter = 0}};
{keep_state, State#state{channel_pid = undefined, has_session = false, heartbeat_counter = 0}}; end;
%% %%
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{}) -> handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{}) ->
@ -398,34 +415,22 @@ flush_reply(Ref) ->
request_ref() -> request_ref() ->
crypto:strong_rand_bytes(16). crypto:strong_rand_bytes(16).
-spec maybe_mark_host_offline(binary()) -> ok. -spec maybe_mark_host_online(binary(), integer()) -> {next_status, NStatus :: integer()} | keep_status.
maybe_mark_host_offline(UUID) -> maybe_mark_host_online(UUID, HostStatus) ->
case iot_api_client:get_host_by_uuid(UUID) of case HostStatus of
{ok, #host_info{status = ?HOST_NOT_JOINED}} -> ?HOST_OFFLINE ->
logger:debug("[iot_host] host: ~p, host_maybe_offline, host not joined, can not change to offline", [UUID]), _ = iot_api_client:change_host_status(UUID, ?HOST_ONLINE),
ok; {next_status, ?HOST_ONLINE};
{ok, #host_info{status = ?HOST_OFFLINE}} -> _ ->
logger:debug("[iot_host] host: ~p, host_maybe_offline, host now is offline, do nothing", [UUID]), keep_status
ok;
{ok, #host_info{status = ?HOST_ONLINE}} ->
_ = iot_api_client:change_host_status(UUID, ?HOST_OFFLINE),
ok;
Other ->
logger:warning("[iot_host] host: ~p, load status failed while marking offline: ~p", [UUID, Other]),
ok
end. end.
-spec maybe_mark_host_online(binary()) -> ok. -spec maybe_mark_host_offline(binary(), integer()) -> {next_status, NStatus :: integer()} | keep_status.
maybe_mark_host_online(UUID) -> maybe_mark_host_offline(UUID, HostStatus) ->
case iot_api_client:get_host_by_uuid(UUID) of case HostStatus of
{ok, #host_info{status = ?HOST_OFFLINE}} -> ?HOST_ONLINE ->
_ = iot_api_client:change_host_status(UUID, ?HOST_ONLINE), _ = iot_api_client:change_host_status(UUID, ?HOST_OFFLINE),
ok; {next_status, ?HOST_OFFLINE};
{ok, #host_info{status = ?HOST_ONLINE}} -> _ ->
ok; keep_status
{ok, #host_info{status = ?HOST_NOT_JOINED}} -> end.
ok;
Other ->
logger:warning("[iot_host] host: ~p, load status failed while marking online: ~p", [UUID, Other]),
ok
end.