Feng пре 10 година
родитељ
комит
78288e8088
1 измењених фајлова са 37 додато и 38 уклоњено
  1. 37 38
      src/emqttd_keepalive.erl

+ 37 - 38
src/emqttd_keepalive.erl

@@ -23,62 +23,61 @@
 %%%
 %%% @end
 %%%-----------------------------------------------------------------------------
+
 -module(emqttd_keepalive).
 
 -author("Feng Lee <feng@emqtt.io>").
 
--export([new/3, resume/1, cancel/1]).
+-export([start/3, check/1, cancel/1]).
 
--record(keepalive, {transport,
-                    socket,
-                    recv_oct,
-                    timeout_sec,
-                    timeout_msg,
-                    timer_ref}).
+-record(keepalive, {statfun, statval,
+                    tsec, tmsg, tref,
+                    repeat = 0}).
 
 %%------------------------------------------------------------------------------
-%% @doc Create a keepalive
+%% @doc Start a keepalive
 %% @end
 %%------------------------------------------------------------------------------
-new({Transport, Socket}, TimeoutSec, TimeoutMsg) when TimeoutSec > 0 ->
-    {ok, [{recv_oct, RecvOct}]} = Transport:getstat(Socket, [recv_oct]),
-	Ref = erlang:send_after(timer:seconds(TimeoutSec), self(), TimeoutMsg),
-	#keepalive {transport   = Transport,
-                socket      = Socket, 
-                recv_oct    = RecvOct, 
-                timeout_sec = TimeoutSec, 
-                timeout_msg = TimeoutMsg,
-                timer_ref   = Ref}.
+start(_, 0, _) ->
+    undefined;
+start(StatFun, TimeoutSec, TimeoutMsg) ->
+    {ok, StatVal} = StatFun(),
+	#keepalive{statfun = StatFun, statval = StatVal,
+               tsec = TimeoutSec, tmsg = TimeoutMsg,
+               tref = timer(TimeoutSec, TimeoutMsg)}.
 
 %%------------------------------------------------------------------------------
-%% @doc Try to resume keepalive, called when timeout
+%% @doc Check keepalive, called when timeout.
 %% @end
 %%------------------------------------------------------------------------------
-resume(KeepAlive = #keepalive {transport   = Transport, 
-                               socket      = Socket, 
-                               recv_oct    = RecvOct, 
-                               timeout_sec = TimeoutSec, 
-                               timeout_msg = TimeoutMsg, 
-                               timer_ref   = Ref }) ->
-    {ok, [{recv_oct, NewRecvOct}]} = Transport:getstat(Socket, [recv_oct]),
-    if
-        NewRecvOct =:= RecvOct -> 
-            timeout;
-        true ->
-            %need?
-            cancel(Ref),
-            NewRef = erlang:send_after(timer:seconds(TimeoutSec), self(), TimeoutMsg),
-            {resumed, KeepAlive#keepalive{recv_oct = NewRecvOct, timer_ref = NewRef}}
+check(KeepAlive = #keepalive{statfun = StatFun, statval = LastVal, repeat = Repeat}) ->
+    case StatFun() of
+        {ok, NewVal} ->
+            if NewVal =/= LastVal ->
+                    {ok, resume(KeepAlive#keepalive{statval = NewVal, repeat = 0})};
+                Repeat < 1 ->
+                    {ok, resume(KeepAlive#keepalive{statval = NewVal, repeat = Repeat + 1})};
+                true ->
+                    {error, timeout}
+            end;
+        {error, Error} ->
+            {error, Error}
     end.
 
+resume(KeepAlive = #keepalive{tsec = TimeoutSec, tmsg = TimeoutMsg}) ->
+    KeepAlive#keepalive{tref = timer(TimeoutSec, TimeoutMsg)}.
+
 %%------------------------------------------------------------------------------
 %% @doc Cancel Keepalive
 %% @end
 %%------------------------------------------------------------------------------
-cancel(#keepalive{timer_ref = Ref}) ->
-    cancel(Ref);
+cancel(#keepalive{tref = TRef}) ->
+    cancel(TRef);
 cancel(undefined) -> 
-	undefined;
-cancel(Ref) -> 
-	catch erlang:cancel_timer(Ref).
+	ok;
+cancel(TRef) ->
+	catch erlang:cancel_timer(TRef).
+
+timer(Sec, Msg) ->
+    erlang:send_after(timer:seconds(Sec), self(), Msg).