fix zd
This commit is contained in:
parent
2b2bac9432
commit
772d0fbb3f
@ -35,7 +35,9 @@
|
|||||||
is_busy = false :: boolean(),
|
is_busy = false :: boolean(),
|
||||||
|
|
||||||
%% 记录成功处理的消息数
|
%% 记录成功处理的消息数
|
||||||
acc_num = 0
|
acc_num = 0,
|
||||||
|
|
||||||
|
queue = queue:new()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -71,13 +73,11 @@ start_link() ->
|
|||||||
init([]) ->
|
init([]) ->
|
||||||
{ok, Opts} = application:get_env(iot, zhongdian),
|
{ok, Opts} = application:get_env(iot, zhongdian),
|
||||||
|
|
||||||
erlang:process_flag(trap_exit, true),
|
{ok, PostmanPid} = create_postman(Opts),
|
||||||
%% 创建转发器, 避免阻塞当前进程的创建,因此采用了延时初始化的机制
|
|
||||||
erlang:start_timer(0, self(), create_postman),
|
|
||||||
%% 启动日志记录器
|
%% 启动日志记录器
|
||||||
{ok, LoggerPid} = iot_logger:start_link("north_data"),
|
{ok, LoggerPid} = iot_logger:start_link("north_data_fix"),
|
||||||
|
|
||||||
{ok, disconnected, #state{mqtt_opts = Opts, postman_pid = undefined, logger_pid = LoggerPid}}.
|
{ok, connected, #state{mqtt_opts = Opts, postman_pid = PostmanPid, logger_pid = LoggerPid}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
%% @doc This function is called by a gen_statem when it needs to find out
|
%% @doc This function is called by a gen_statem when it needs to find out
|
||||||
@ -91,31 +91,28 @@ callback_mode() ->
|
|||||||
%% functions is called when gen_statem receives and event from
|
%% functions is called when gen_statem receives and event from
|
||||||
%% call/2, cast/2, or as a normal process message.
|
%% call/2, cast/2, or as a normal process message.
|
||||||
|
|
||||||
handle_event(cast, {forward, LocationCode, Fields, Timestamp}, StateName, State = #state{is_busy = IsBusy}) ->
|
handle_event(cast, {forward, LocationCode, Fields, Timestamp}, StateName, State = #state{is_busy = IsBusy, queue = Q}) ->
|
||||||
mnesia_queue:insert(#north_data{location_code = LocationCode, fields = Fields, timestamp = Timestamp}),
|
Q1 = queue:in(#north_data{location_code = LocationCode, fields = Fields, timestamp = Timestamp}, Q),
|
||||||
%% 避免不必要的内部消息
|
%% 避免不必要的内部消息
|
||||||
Actions = case StateName =:= connected andalso not IsBusy of
|
Actions = case StateName =:= connected andalso not IsBusy of
|
||||||
true -> [{next_event, info, fetch_next}];
|
true -> [{next_event, info, fetch_next}];
|
||||||
false -> []
|
false -> []
|
||||||
end,
|
end,
|
||||||
{keep_state, State, Actions};
|
{keep_state, State#state{queue = Q1}, Actions};
|
||||||
|
|
||||||
%% 触发读取下一条数据
|
%% 触发读取下一条数据
|
||||||
handle_event(info, fetch_next, disconnected, State) ->
|
|
||||||
lager:debug("[iot_zd_endpoint] fetch_next postman offline, data in queue"),
|
|
||||||
{keep_state, State};
|
|
||||||
handle_event(info, fetch_next, connected, State = #state{is_busy = true}) ->
|
handle_event(info, fetch_next, connected, State = #state{is_busy = true}) ->
|
||||||
{keep_state, State};
|
{keep_state, State};
|
||||||
handle_event(info, fetch_next, connected, State = #state{postman_pid = PostmanPid, cursor = Cursor}) ->
|
handle_event(info, fetch_next, connected, State = #state{postman_pid = PostmanPid, queue = Q}) ->
|
||||||
case mnesia_queue:dirty_fetch_next(Cursor) of
|
case queue:out(Q) of
|
||||||
{ok, NCursor, NorthData} ->
|
{{value, NorthData}, Q1} ->
|
||||||
lager:debug("[iot_zd_endpoint] fetch_next success, north data is: ~p", [NorthData]),
|
lager:debug("[iot_zd_endpoint] fetch_next success, north data is: ~p", [NorthData]),
|
||||||
do_post(PostmanPid, NorthData),
|
do_post(PostmanPid, NorthData),
|
||||||
TimerRef = erlang:start_timer(?RETRY_INTERVAL, self(), {repost_ticker, NorthData}),
|
TimerRef = erlang:start_timer(?RETRY_INTERVAL, self(), {repost_ticker, NorthData}),
|
||||||
|
|
||||||
{keep_state, State#state{cursor = NCursor, timer_ref = TimerRef, is_busy = true}};
|
{keep_state, State#state{queue = Q1, timer_ref = TimerRef, is_busy = true}};
|
||||||
'$end_of_table' ->
|
{empty, Q1} ->
|
||||||
{keep_state, State}
|
{keep_state, State#state{queue = Q1}}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% 收到确认消息
|
%% 收到确认消息
|
||||||
@ -123,7 +120,6 @@ handle_event(info, {ack, Id, AssocMessage}, StateName, State = #state{timer_ref
|
|||||||
%% 记录日志信息
|
%% 记录日志信息
|
||||||
iot_logger:write(LoggerPid, AssocMessage),
|
iot_logger:write(LoggerPid, AssocMessage),
|
||||||
|
|
||||||
ok = mnesia_queue:delete(Id),
|
|
||||||
lager:debug("[iot_zd_endpoint] get ack: ~p", [Id]),
|
lager:debug("[iot_zd_endpoint] get ack: ~p", [Id]),
|
||||||
Actions = case StateName =:= connected of
|
Actions = case StateName =:= connected of
|
||||||
true -> [{next_event, info, fetch_next}];
|
true -> [{next_event, info, fetch_next}];
|
||||||
@ -145,35 +141,14 @@ handle_event(info, {timeout, _, {repost_ticker, NorthData}}, connected, State =
|
|||||||
handle_event(info, {timeout, _, {repost_ticker, _}}, disconnected, State) ->
|
handle_event(info, {timeout, _, {repost_ticker, _}}, disconnected, State) ->
|
||||||
{keep_state, State};
|
{keep_state, State};
|
||||||
|
|
||||||
handle_event(info, {timeout, _, create_postman}, disconnected, State = #state{mqtt_opts = Opts}) ->
|
|
||||||
lager:debug("[iot_zd_endpoint] create postman"),
|
|
||||||
try
|
|
||||||
{ok, PostmanPid} = create_postman(Opts),
|
|
||||||
{next_state, connected, State#state{postman_pid = PostmanPid, timer_ref = undefined, is_busy = false}, [{next_event, info, fetch_next}]}
|
|
||||||
catch _:Error:Stack ->
|
|
||||||
lager:warning("[iot_zd_endpoint] config: ~p, create postman get error: ~p, stack: ~p", [Opts, Error, Stack]),
|
|
||||||
erlang:start_timer(?RETRY_INTERVAL, self(), create_postman),
|
|
||||||
|
|
||||||
{keep_state, State#state{postman_pid = undefined}}
|
|
||||||
end;
|
|
||||||
|
|
||||||
%% 获取当前统计信息
|
%% 获取当前统计信息
|
||||||
handle_event({call, From}, get_stat, StateName, State = #state{acc_num = AccNum}) ->
|
handle_event({call, From}, get_stat, StateName, State = #state{acc_num = AccNum}) ->
|
||||||
Stat = #{
|
Stat = #{
|
||||||
<<"acc_num">> => AccNum,
|
<<"acc_num">> => AccNum,
|
||||||
<<"queue_num">> => mnesia_queue:table_size(),
|
|
||||||
<<"state_name">> => atom_to_binary(StateName)
|
<<"state_name">> => atom_to_binary(StateName)
|
||||||
},
|
},
|
||||||
{keep_state, State, [{reply, From, Stat}]};
|
{keep_state, State, [{reply, From, Stat}]};
|
||||||
|
|
||||||
%% postman进程挂掉时,重新建立新的
|
|
||||||
handle_event(info, {'EXIT', PostmanPid, Reason}, connected, State = #state{timer_ref = TimerRef, postman_pid = PostmanPid}) ->
|
|
||||||
lager:warning("[iot_zd_endpoint] postman exited with reason: ~p", [Reason]),
|
|
||||||
is_reference(TimerRef) andalso erlang:cancel_timer(TimerRef),
|
|
||||||
erlang:start_timer(?RETRY_INTERVAL, self(), create_postman),
|
|
||||||
|
|
||||||
{next_state, disconnected, State#state{timer_ref = undefined, postman_pid = undefined}};
|
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
%% @doc If callback_mode is handle_event_function, then whenever a
|
%% @doc If callback_mode is handle_event_function, then whenever a
|
||||||
%% gen_statem receives an event from call/2, cast/2, or as a normal
|
%% gen_statem receives an event from call/2, cast/2, or as a normal
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user