fix host status
This commit is contained in:
parent
fe46aff527
commit
b8d3d4b524
@ -215,11 +215,12 @@ handle_event({call, From}, get_metric, _, State = #state{metrics = Metrics}) ->
|
||||
{keep_state, State, [{reply, From, {ok, Metrics}}]};
|
||||
|
||||
%% 获取主机的状态
|
||||
handle_event({call, From}, get_status, _, State = #state{channel_pid = ChannelPid, heartbeat_counter = HeartbeatCounter, metrics = Metrics, has_session = HasSession}) ->
|
||||
handle_event({call, From}, get_status, _, State = #state{channel_pid = ChannelPid, heartbeat_counter = HeartbeatCounter, metrics = Metrics, has_session = HasSession, host_status = HostStatus}) ->
|
||||
HasChannel = (ChannelPid /= undefined),
|
||||
Reply = #{
|
||||
<<"has_channel">> => HasChannel,
|
||||
<<"has_session">> => HasSession,
|
||||
<<"host_status">> => HostStatus,
|
||||
<<"heartbeat_counter">> => HeartbeatCounter,
|
||||
<<"metrics">> => Metrics
|
||||
},
|
||||
@ -271,23 +272,21 @@ handle_event({call, From}, {activate, Auth}, _, State = #state{uuid = UUID}) ->
|
||||
{next_state, NStateName, State, [{reply, From, ok}]};
|
||||
|
||||
%% 绑定channel
|
||||
handle_event({call, From}, {attach_channel, ChannelPid}, StateName, State = #state{uuid = UUID, channel_pid = OldChannelPid}) ->
|
||||
handle_event({call, From}, {attach_channel, ChannelPid}, StateName, State = #state{uuid = UUID, channel_pid = OldChannelPid, host_status = HostStatus}) ->
|
||||
case OldChannelPid == undefined orelse OldChannelPid =:= ChannelPid of
|
||||
true ->
|
||||
case StateName of
|
||||
?STATE_ACTIVATED ->
|
||||
erlang:monitor(process, ChannelPid),
|
||||
%% 更新主机为在线状态
|
||||
ChangeResult = iot_api_client:change_host_status(UUID, ?HOST_ONLINE),
|
||||
logger:debug("[iot_host] host_id(attach_channel) uuid: ~p, will change status, result: ~p", [UUID, ChangeResult]),
|
||||
{keep_state, State#state{channel_pid = ChannelPid, has_session = true}, [{reply, From, ok}]};
|
||||
NState = mark_host_online(UUID, HostStatus, State#state{channel_pid = ChannelPid, has_session = true}),
|
||||
{keep_state, NState, [{reply, From, ok}]};
|
||||
%% 主机未激活
|
||||
?STATE_DENIED ->
|
||||
logger:notice("[iot_host] attach_channel host_id uuid: ~p, channel: ~p, host denied locally", [UUID, ChannelPid]),
|
||||
erlang:monitor(process, ChannelPid),
|
||||
ChangeResult = iot_api_client:change_host_status(UUID, ?HOST_ONLINE),
|
||||
logger:debug("[iot_host] host_id(attach_channel) uuid: ~p, denied but online, change status result: ~p", [UUID, ChangeResult]),
|
||||
{keep_state, State#state{channel_pid = ChannelPid, has_session = true}, [{reply, From, ok}]}
|
||||
NState = mark_host_online(UUID, HostStatus, State#state{channel_pid = ChannelPid, has_session = true}),
|
||||
{keep_state, NState, [{reply, From, ok}]}
|
||||
end;
|
||||
false ->
|
||||
logger:notice("[iot_host] attach_channel host_id uuid: ~p, old channel exists: ~p", [UUID, OldChannelPid]),
|
||||
@ -313,12 +312,8 @@ handle_event(cast, {handle, {ping, Metrics}}, ?STATE_ACTIVATED, State = #state{u
|
||||
|
||||
%% 心跳机制
|
||||
handle_event(cast, heartbeat, _, State = #state{uuid = UUID, heartbeat_counter = HeartbeatCounter, host_status = HostStatus}) ->
|
||||
case maybe_mark_host_online(UUID, HostStatus) of
|
||||
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;
|
||||
NState = mark_host_online(UUID, HostStatus, State#state{heartbeat_counter = HeartbeatCounter + 1}),
|
||||
{keep_state, NState};
|
||||
|
||||
%% UDP 心跳丢失但 SSL channel 仍在时,不能把 host 标记为离线。
|
||||
handle_event(info, {timeout, _, heartbeat_ticker}, _,
|
||||
@ -326,24 +321,15 @@ handle_event(info, {timeout, _, heartbeat_ticker}, _,
|
||||
|
||||
erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker),
|
||||
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;
|
||||
NState = mark_host_online(UUID, HostStatus, State#state{heartbeat_counter = 0}),
|
||||
{keep_state, NState};
|
||||
|
||||
%% 没有收到 UDP 心跳且没有 SSL channel,主机下线, 设备状态不变
|
||||
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]),
|
||||
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}};
|
||||
|
||||
end;
|
||||
NState = mark_host_offline(UUID, HostStatus, State#state{channel_pid = undefined, has_session = false, heartbeat_counter = 0}),
|
||||
{keep_state, NState};
|
||||
|
||||
%% 其他情况下需要重置系统计数器
|
||||
handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{}) ->
|
||||
@ -393,10 +379,11 @@ get_route_key(RouteKey) when is_binary(RouteKey) ->
|
||||
RouteKey.
|
||||
|
||||
%% 将当前的state转换成map
|
||||
state_map(#state{host_id = HostId, uuid = UUID, has_session = HasSession, heartbeat_counter = HeartbeatCounter, channel_pid = ChannelPid, metrics = Metrics}) ->
|
||||
state_map(#state{host_id = HostId, uuid = UUID, host_status = HostStatus, has_session = HasSession, heartbeat_counter = HeartbeatCounter, channel_pid = ChannelPid, metrics = Metrics}) ->
|
||||
#{
|
||||
host_id => HostId,
|
||||
uuid => UUID,
|
||||
host_status => HostStatus,
|
||||
has_session => HasSession,
|
||||
heartbeat_counter => HeartbeatCounter,
|
||||
channel_pid => ChannelPid,
|
||||
@ -415,12 +402,36 @@ flush_reply(Ref) ->
|
||||
request_ref() ->
|
||||
crypto:strong_rand_bytes(16).
|
||||
|
||||
-spec mark_host_online(binary(), integer(), #state{}) -> #state{}.
|
||||
mark_host_online(UUID, HostStatus, State) ->
|
||||
case maybe_mark_host_online(UUID, HostStatus) of
|
||||
keep_status ->
|
||||
State;
|
||||
{next_status, NStatus} ->
|
||||
State#state{host_status = NStatus}
|
||||
end.
|
||||
|
||||
-spec mark_host_offline(binary(), integer(), #state{}) -> #state{}.
|
||||
mark_host_offline(UUID, HostStatus, State) ->
|
||||
case maybe_mark_host_offline(UUID, HostStatus) of
|
||||
keep_status ->
|
||||
State;
|
||||
{next_status, NStatus} ->
|
||||
State#state{host_status = NStatus}
|
||||
end.
|
||||
|
||||
-spec maybe_mark_host_online(binary(), integer()) -> {next_status, NStatus :: integer()} | keep_status.
|
||||
maybe_mark_host_online(UUID, HostStatus) ->
|
||||
case HostStatus of
|
||||
?HOST_OFFLINE ->
|
||||
_ = iot_api_client:change_host_status(UUID, ?HOST_ONLINE),
|
||||
{next_status, ?HOST_ONLINE};
|
||||
case iot_api_client:change_host_status(UUID, ?HOST_ONLINE) of
|
||||
{ok, Result} ->
|
||||
logger:debug("[iot_host] uuid: ~p, change host status online success: ~p", [UUID, Result]),
|
||||
{next_status, ?HOST_ONLINE};
|
||||
{error, Reason} ->
|
||||
logger:warning("[iot_host] uuid: ~p, change host status online failed: ~p", [UUID, Reason]),
|
||||
keep_status
|
||||
end;
|
||||
_ ->
|
||||
keep_status
|
||||
end.
|
||||
@ -429,8 +440,14 @@ maybe_mark_host_online(UUID, HostStatus) ->
|
||||
maybe_mark_host_offline(UUID, HostStatus) ->
|
||||
case HostStatus of
|
||||
?HOST_ONLINE ->
|
||||
_ = iot_api_client:change_host_status(UUID, ?HOST_OFFLINE),
|
||||
{next_status, ?HOST_OFFLINE};
|
||||
case iot_api_client:change_host_status(UUID, ?HOST_OFFLINE) of
|
||||
{ok, Result} ->
|
||||
logger:debug("[iot_host] uuid: ~p, change host status offline success: ~p", [UUID, Result]),
|
||||
{next_status, ?HOST_OFFLINE};
|
||||
{error, Reason} ->
|
||||
logger:warning("[iot_host] uuid: ~p, change host status offline failed: ~p", [UUID, Reason]),
|
||||
keep_status
|
||||
end;
|
||||
_ ->
|
||||
keep_status
|
||||
end.
|
||||
Loading…
x
Reference in New Issue
Block a user