|
@@ -50,7 +50,7 @@
|
|
|
|
|
|
|
|
-logger_header("[Session]").
|
|
-logger_header("[Session]").
|
|
|
|
|
|
|
|
--export([init/3]).
|
|
|
|
|
|
|
+-export([init/2]).
|
|
|
|
|
|
|
|
-export([ info/1
|
|
-export([ info/1
|
|
|
, info/2
|
|
, info/2
|
|
@@ -58,10 +58,6 @@
|
|
|
, stats/1
|
|
, stats/1
|
|
|
]).
|
|
]).
|
|
|
|
|
|
|
|
--export([ takeover/1
|
|
|
|
|
- , resume/2
|
|
|
|
|
- ]).
|
|
|
|
|
-
|
|
|
|
|
-export([ subscribe/4
|
|
-export([ subscribe/4
|
|
|
, unsubscribe/3
|
|
, unsubscribe/3
|
|
|
]).
|
|
]).
|
|
@@ -73,71 +69,51 @@
|
|
|
, pubcomp/2
|
|
, pubcomp/2
|
|
|
]).
|
|
]).
|
|
|
|
|
|
|
|
--export([deliver/2]).
|
|
|
|
|
|
|
+-export([ deliver/2
|
|
|
|
|
+ , retry/1
|
|
|
|
|
+ ]).
|
|
|
|
|
|
|
|
--export([timeout/3]).
|
|
|
|
|
|
|
+-export([ takeover/1
|
|
|
|
|
+ , resume/2
|
|
|
|
|
+ ]).
|
|
|
|
|
|
|
|
--export_type([session/0]).
|
|
|
|
|
|
|
+-export([expire/2]).
|
|
|
|
|
|
|
|
--import(emqx_zone,
|
|
|
|
|
- [ get_env/2
|
|
|
|
|
- , get_env/3
|
|
|
|
|
- ]).
|
|
|
|
|
|
|
+-export_type([session/0]).
|
|
|
|
|
|
|
|
%% For test case
|
|
%% For test case
|
|
|
-export([set_pkt_id/2]).
|
|
-export([set_pkt_id/2]).
|
|
|
|
|
|
|
|
--record(session, {
|
|
|
|
|
- %% Clean Start Flag
|
|
|
|
|
- clean_start :: boolean(),
|
|
|
|
|
|
|
+-import(emqx_zone, [get_env/3]).
|
|
|
|
|
|
|
|
|
|
+-record(session, {
|
|
|
%% Client’s Subscriptions.
|
|
%% Client’s Subscriptions.
|
|
|
subscriptions :: map(),
|
|
subscriptions :: map(),
|
|
|
-
|
|
|
|
|
%% Max subscriptions allowed
|
|
%% Max subscriptions allowed
|
|
|
max_subscriptions :: non_neg_integer(),
|
|
max_subscriptions :: non_neg_integer(),
|
|
|
-
|
|
|
|
|
%% Upgrade QoS?
|
|
%% Upgrade QoS?
|
|
|
upgrade_qos :: boolean(),
|
|
upgrade_qos :: boolean(),
|
|
|
-
|
|
|
|
|
%% Client <- Broker:
|
|
%% Client <- Broker:
|
|
|
%% Inflight QoS1, QoS2 messages sent to the client but unacked.
|
|
%% Inflight QoS1, QoS2 messages sent to the client but unacked.
|
|
|
inflight :: emqx_inflight:inflight(),
|
|
inflight :: emqx_inflight:inflight(),
|
|
|
-
|
|
|
|
|
%% All QoS1, QoS2 messages published to when client is disconnected.
|
|
%% All QoS1, QoS2 messages published to when client is disconnected.
|
|
|
%% QoS 1 and QoS 2 messages pending transmission to the Client.
|
|
%% QoS 1 and QoS 2 messages pending transmission to the Client.
|
|
|
%%
|
|
%%
|
|
|
%% Optionally, QoS 0 messages pending transmission to the Client.
|
|
%% Optionally, QoS 0 messages pending transmission to the Client.
|
|
|
mqueue :: emqx_mqueue:mqueue(),
|
|
mqueue :: emqx_mqueue:mqueue(),
|
|
|
-
|
|
|
|
|
%% Next packet id of the session
|
|
%% Next packet id of the session
|
|
|
next_pkt_id = 1 :: emqx_types:packet_id(),
|
|
next_pkt_id = 1 :: emqx_types:packet_id(),
|
|
|
-
|
|
|
|
|
%% Retry interval for redelivering QoS1/2 messages
|
|
%% Retry interval for redelivering QoS1/2 messages
|
|
|
retry_interval :: timeout(),
|
|
retry_interval :: timeout(),
|
|
|
-
|
|
|
|
|
- %% Retry delivery timer
|
|
|
|
|
- retry_timer :: maybe(reference()),
|
|
|
|
|
-
|
|
|
|
|
%% Client -> Broker:
|
|
%% Client -> Broker:
|
|
|
%% Inflight QoS2 messages received from client and waiting for pubrel.
|
|
%% Inflight QoS2 messages received from client and waiting for pubrel.
|
|
|
awaiting_rel :: map(),
|
|
awaiting_rel :: map(),
|
|
|
-
|
|
|
|
|
%% Max Packets Awaiting PUBREL
|
|
%% Max Packets Awaiting PUBREL
|
|
|
max_awaiting_rel :: non_neg_integer(),
|
|
max_awaiting_rel :: non_neg_integer(),
|
|
|
-
|
|
|
|
|
- %% Awaiting PUBREL Timer
|
|
|
|
|
- await_rel_timer :: maybe(reference()),
|
|
|
|
|
-
|
|
|
|
|
%% Awaiting PUBREL Timeout
|
|
%% Awaiting PUBREL Timeout
|
|
|
await_rel_timeout :: timeout(),
|
|
await_rel_timeout :: timeout(),
|
|
|
-
|
|
|
|
|
%% Session Expiry Interval
|
|
%% Session Expiry Interval
|
|
|
expiry_interval :: timeout(),
|
|
expiry_interval :: timeout(),
|
|
|
-
|
|
|
|
|
- %% Expired Timer
|
|
|
|
|
- expiry_timer :: maybe(reference()),
|
|
|
|
|
-
|
|
|
|
|
%% Created at
|
|
%% Created at
|
|
|
created_at :: erlang:timestamp()
|
|
created_at :: erlang:timestamp()
|
|
|
}).
|
|
}).
|
|
@@ -153,11 +129,10 @@
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
|
|
%% @doc Init a session.
|
|
%% @doc Init a session.
|
|
|
--spec(init(boolean(), emqx_types:client(), Options :: map()) -> session()).
|
|
|
|
|
-init(CleanStart, #{zone := Zone}, #{max_inflight := MaxInflight,
|
|
|
|
|
- expiry_interval := ExpiryInterval}) ->
|
|
|
|
|
- #session{clean_start = CleanStart,
|
|
|
|
|
- max_subscriptions = get_env(Zone, max_subscriptions, 0),
|
|
|
|
|
|
|
+-spec(init(emqx_types:client(), Options :: map()) -> session()).
|
|
|
|
|
+init(#{zone := Zone}, #{max_inflight := MaxInflight,
|
|
|
|
|
+ expiry_interval := ExpiryInterval}) ->
|
|
|
|
|
+ #session{max_subscriptions = get_env(Zone, max_subscriptions, 0),
|
|
|
subscriptions = #{},
|
|
subscriptions = #{},
|
|
|
upgrade_qos = get_env(Zone, upgrade_qos, false),
|
|
upgrade_qos = get_env(Zone, upgrade_qos, false),
|
|
|
inflight = emqx_inflight:new(MaxInflight),
|
|
inflight = emqx_inflight:new(MaxInflight),
|
|
@@ -183,8 +158,7 @@ init_mqueue(Zone) ->
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
|
|
-spec(info(session()) -> emqx_types:infos()).
|
|
-spec(info(session()) -> emqx_types:infos()).
|
|
|
-info(#session{clean_start = CleanStart,
|
|
|
|
|
- max_subscriptions = MaxSubscriptions,
|
|
|
|
|
|
|
+info(#session{max_subscriptions = MaxSubscriptions,
|
|
|
subscriptions = Subscriptions,
|
|
subscriptions = Subscriptions,
|
|
|
upgrade_qos = UpgradeQoS,
|
|
upgrade_qos = UpgradeQoS,
|
|
|
inflight = Inflight,
|
|
inflight = Inflight,
|
|
@@ -196,8 +170,7 @@ info(#session{clean_start = CleanStart,
|
|
|
await_rel_timeout = AwaitRelTimeout,
|
|
await_rel_timeout = AwaitRelTimeout,
|
|
|
expiry_interval = ExpiryInterval,
|
|
expiry_interval = ExpiryInterval,
|
|
|
created_at = CreatedAt}) ->
|
|
created_at = CreatedAt}) ->
|
|
|
- #{clean_start => CleanStart,
|
|
|
|
|
- subscriptions => Subscriptions,
|
|
|
|
|
|
|
+ #{subscriptions => Subscriptions,
|
|
|
max_subscriptions => MaxSubscriptions,
|
|
max_subscriptions => MaxSubscriptions,
|
|
|
upgrade_qos => UpgradeQoS,
|
|
upgrade_qos => UpgradeQoS,
|
|
|
inflight => emqx_inflight:size(Inflight),
|
|
inflight => emqx_inflight:size(Inflight),
|
|
@@ -214,8 +187,6 @@ info(#session{clean_start = CleanStart,
|
|
|
created_at => CreatedAt
|
|
created_at => CreatedAt
|
|
|
}.
|
|
}.
|
|
|
|
|
|
|
|
-info(clean_start, #session{clean_start = CleanStart}) ->
|
|
|
|
|
- CleanStart;
|
|
|
|
|
info(subscriptions, #session{subscriptions = Subs}) ->
|
|
info(subscriptions, #session{subscriptions = Subs}) ->
|
|
|
Subs;
|
|
Subs;
|
|
|
info(max_subscriptions, #session{max_subscriptions = MaxSubs}) ->
|
|
info(max_subscriptions, #session{max_subscriptions = MaxSubs}) ->
|
|
@@ -254,11 +225,9 @@ info(created_at, #session{created_at = CreatedAt}) ->
|
|
|
-spec(attrs(session()) -> emqx_types:attrs()).
|
|
-spec(attrs(session()) -> emqx_types:attrs()).
|
|
|
attrs(undefined) ->
|
|
attrs(undefined) ->
|
|
|
#{};
|
|
#{};
|
|
|
-attrs(#session{clean_start = CleanStart,
|
|
|
|
|
- expiry_interval = ExpiryInterval,
|
|
|
|
|
|
|
+attrs(#session{expiry_interval = ExpiryInterval,
|
|
|
created_at = CreatedAt}) ->
|
|
created_at = CreatedAt}) ->
|
|
|
- #{clean_start => CleanStart,
|
|
|
|
|
- expiry_interval => ExpiryInterval,
|
|
|
|
|
|
|
+ #{expiry_interval => ExpiryInterval,
|
|
|
created_at => CreatedAt
|
|
created_at => CreatedAt
|
|
|
}.
|
|
}.
|
|
|
|
|
|
|
@@ -290,7 +259,7 @@ takeover(#session{subscriptions = Subs}) ->
|
|
|
ok = emqx_broker:unsubscribe(TopicFilter)
|
|
ok = emqx_broker:unsubscribe(TopicFilter)
|
|
|
end, maps:to_list(Subs)).
|
|
end, maps:to_list(Subs)).
|
|
|
|
|
|
|
|
--spec(resume(emqx_types:client_id(), session()) -> {ok, session()}).
|
|
|
|
|
|
|
+-spec(resume(emqx_types:client_id(), session()) -> session()).
|
|
|
resume(ClientId, Session = #session{subscriptions = Subs}) ->
|
|
resume(ClientId, Session = #session{subscriptions = Subs}) ->
|
|
|
?LOG(info, "Session is resumed."),
|
|
?LOG(info, "Session is resumed."),
|
|
|
%% 1. Subscribe again
|
|
%% 1. Subscribe again
|
|
@@ -300,8 +269,8 @@ resume(ClientId, Session = #session{subscriptions = Subs}) ->
|
|
|
%% 2. Run hooks.
|
|
%% 2. Run hooks.
|
|
|
ok = emqx_hooks:run('session.resumed', [#{client_id => ClientId}, attrs(Session)]),
|
|
ok = emqx_hooks:run('session.resumed', [#{client_id => ClientId}, attrs(Session)]),
|
|
|
%% TODO: 3. Redeliver: Replay delivery and Dequeue pending messages
|
|
%% TODO: 3. Redeliver: Replay delivery and Dequeue pending messages
|
|
|
- %% noreply(ensure_stats_timer(dequeue(retry_delivery(true, State1))));
|
|
|
|
|
- {ok, Session}.
|
|
|
|
|
|
|
+ %% noreply(dequeue(retry_delivery(true, State1)));
|
|
|
|
|
+ Session.
|
|
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Client -> Broker: SUBSCRIBE
|
|
%% Client -> Broker: SUBSCRIBE
|
|
@@ -388,7 +357,7 @@ do_publish(PacketId, Msg = #message{timestamp = Ts},
|
|
|
DeliverResults = emqx_broker:publish(Msg),
|
|
DeliverResults = emqx_broker:publish(Msg),
|
|
|
AwaitingRel1 = maps:put(PacketId, Ts, AwaitingRel),
|
|
AwaitingRel1 = maps:put(PacketId, Ts, AwaitingRel),
|
|
|
Session1 = Session#session{awaiting_rel = AwaitingRel1},
|
|
Session1 = Session#session{awaiting_rel = AwaitingRel1},
|
|
|
- {ok, DeliverResults, ensure_await_rel_timer(Session1)};
|
|
|
|
|
|
|
+ {ok, DeliverResults, Session1};
|
|
|
true ->
|
|
true ->
|
|
|
{error, ?RC_PACKET_IDENTIFIER_IN_USE}
|
|
{error, ?RC_PACKET_IDENTIFIER_IN_USE}
|
|
|
end.
|
|
end.
|
|
@@ -544,9 +513,8 @@ enqueue(Msg, Session = #session{mqueue = Q}) ->
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
|
|
await(PacketId, Msg, Session = #session{inflight = Inflight}) ->
|
|
await(PacketId, Msg, Session = #session{inflight = Inflight}) ->
|
|
|
- Inflight1 = emqx_inflight:insert(
|
|
|
|
|
- PacketId, {Msg, os:timestamp()}, Inflight),
|
|
|
|
|
- ensure_retry_timer(Session#session{inflight = Inflight1}).
|
|
|
|
|
|
|
+ Inflight1 = emqx_inflight:insert(PacketId, {Msg, os:timestamp()}, Inflight),
|
|
|
|
|
+ Session#session{inflight = Inflight1}.
|
|
|
|
|
|
|
|
get_subopts(Topic, SubMap) ->
|
|
get_subopts(Topic, SubMap) ->
|
|
|
case maps:find(Topic, SubMap) of
|
|
case maps:find(Topic, SubMap) of
|
|
@@ -578,44 +546,12 @@ enrich([{rap, _}|Opts], Msg = #message{flags = Flags}, Session) ->
|
|
|
enrich([{subid, SubId}|Opts], Msg, Session) ->
|
|
enrich([{subid, SubId}|Opts], Msg, Session) ->
|
|
|
enrich(Opts, emqx_message:set_header('Subscription-Identifier', SubId, Msg), Session).
|
|
enrich(Opts, emqx_message:set_header('Subscription-Identifier', SubId, Msg), Session).
|
|
|
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-%% Handle timeout
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-
|
|
|
|
|
--spec(timeout(reference(), atom(), session())
|
|
|
|
|
- -> {ok, session()} | {ok, list(), session()}).
|
|
|
|
|
-timeout(TRef, retry_delivery, Session = #session{retry_timer = TRef}) ->
|
|
|
|
|
- retry_delivery(Session#session{retry_timer = undefined});
|
|
|
|
|
-
|
|
|
|
|
-timeout(TRef, check_awaiting_rel, Session = #session{await_rel_timer = TRef}) ->
|
|
|
|
|
- expire_awaiting_rel(Session);
|
|
|
|
|
-
|
|
|
|
|
-timeout(TRef, Msg, Session) ->
|
|
|
|
|
- ?LOG(error, "unexpected timeout - ~p: ~p", [TRef, Msg]),
|
|
|
|
|
- {ok, Session}.
|
|
|
|
|
-
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-%% Ensure retry timer
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-
|
|
|
|
|
-ensure_retry_timer(Session = #session{retry_interval = Interval,
|
|
|
|
|
- retry_timer = undefined}) ->
|
|
|
|
|
- ensure_retry_timer(Interval, Session);
|
|
|
|
|
-ensure_retry_timer(Session) ->
|
|
|
|
|
- Session.
|
|
|
|
|
-
|
|
|
|
|
-ensure_retry_timer(Interval, Session = #session{retry_timer = undefined}) ->
|
|
|
|
|
- TRef = emqx_misc:start_timer(Interval, retry_delivery),
|
|
|
|
|
- Session#session{retry_timer = TRef};
|
|
|
|
|
-ensure_retry_timer(_Interval, Session) ->
|
|
|
|
|
- Session.
|
|
|
|
|
-
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Retry Delivery
|
|
%% Retry Delivery
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
|
|
%% Redeliver at once if force is true
|
|
%% Redeliver at once if force is true
|
|
|
-retry_delivery(Session = #session{inflight = Inflight}) ->
|
|
|
|
|
|
|
+retry(Session = #session{inflight = Inflight}) ->
|
|
|
case emqx_inflight:is_empty(Inflight) of
|
|
case emqx_inflight:is_empty(Inflight) of
|
|
|
true -> {ok, Session};
|
|
true -> {ok, Session};
|
|
|
false ->
|
|
false ->
|
|
@@ -626,10 +562,11 @@ retry_delivery(Session = #session{inflight = Inflight}) ->
|
|
|
|
|
|
|
|
retry_delivery([], _Now, Acc, Session) ->
|
|
retry_delivery([], _Now, Acc, Session) ->
|
|
|
%% Retry again...
|
|
%% Retry again...
|
|
|
- {ok, lists:reverse(Acc), ensure_retry_timer(Session)};
|
|
|
|
|
|
|
+ {ok, lists:reverse(Acc), Session};
|
|
|
|
|
|
|
|
retry_delivery([{PacketId, {Val, Ts}}|More], Now, Acc,
|
|
retry_delivery([{PacketId, {Val, Ts}}|More], Now, Acc,
|
|
|
- Session = #session{retry_interval = Interval, inflight = Inflight}) ->
|
|
|
|
|
|
|
+ Session = #session{retry_interval = Interval,
|
|
|
|
|
+ inflight = Inflight}) ->
|
|
|
%% Microseconds -> MilliSeconds
|
|
%% Microseconds -> MilliSeconds
|
|
|
Age = timer:now_diff(Now, Ts) div 1000,
|
|
Age = timer:now_diff(Now, Ts) div 1000,
|
|
|
if
|
|
if
|
|
@@ -637,7 +574,7 @@ retry_delivery([{PacketId, {Val, Ts}}|More], Now, Acc,
|
|
|
{Acc1, Inflight1} = retry_delivery(PacketId, Val, Now, Acc, Inflight),
|
|
{Acc1, Inflight1} = retry_delivery(PacketId, Val, Now, Acc, Inflight),
|
|
|
retry_delivery(More, Now, Acc1, Session#session{inflight = Inflight1});
|
|
retry_delivery(More, Now, Acc1, Session#session{inflight = Inflight1});
|
|
|
true ->
|
|
true ->
|
|
|
- {ok, lists:reverse(Acc), ensure_retry_timer(Interval - max(0, Age), Session)}
|
|
|
|
|
|
|
+ {ok, lists:reverse(Acc), Interval - max(0, Age), Session}
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
retry_delivery(PacketId, Msg, Now, Acc, Inflight) when is_record(Msg, message) ->
|
|
retry_delivery(PacketId, Msg, Now, Acc, Inflight) when is_record(Msg, message) ->
|
|
@@ -654,34 +591,20 @@ retry_delivery(PacketId, pubrel, Now, Acc, Inflight) ->
|
|
|
Inflight1 = emqx_inflight:update(PacketId, {pubrel, Now}, Inflight),
|
|
Inflight1 = emqx_inflight:update(PacketId, {pubrel, Now}, Inflight),
|
|
|
{[{pubrel, PacketId}|Acc], Inflight1}.
|
|
{[{pubrel, PacketId}|Acc], Inflight1}.
|
|
|
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-%% Ensure await_rel timer
|
|
|
|
|
-%%--------------------------------------------------------------------
|
|
|
|
|
-
|
|
|
|
|
-ensure_await_rel_timer(Session = #session{await_rel_timeout = Timeout,
|
|
|
|
|
- await_rel_timer = undefined}) ->
|
|
|
|
|
- ensure_await_rel_timer(Timeout, Session);
|
|
|
|
|
-ensure_await_rel_timer(Session) ->
|
|
|
|
|
- Session.
|
|
|
|
|
-
|
|
|
|
|
-ensure_await_rel_timer(Timeout, Session = #session{await_rel_timer = undefined}) ->
|
|
|
|
|
- TRef = emqx_misc:start_timer(Timeout, check_awaiting_rel),
|
|
|
|
|
- Session#session{await_rel_timer = TRef};
|
|
|
|
|
-ensure_await_rel_timer(_Timeout, Session) ->
|
|
|
|
|
- Session.
|
|
|
|
|
-
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
%% Expire Awaiting Rel
|
|
%% Expire Awaiting Rel
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|
|
|
|
|
|
|
|
-expire_awaiting_rel(Session = #session{awaiting_rel = AwaitingRel}) ->
|
|
|
|
|
|
|
+expire(awaiting_rel, Session = #session{awaiting_rel = AwaitingRel}) ->
|
|
|
case maps:size(AwaitingRel) of
|
|
case maps:size(AwaitingRel) of
|
|
|
0 -> {ok, Session};
|
|
0 -> {ok, Session};
|
|
|
- _ -> expire_awaiting_rel(lists:keysort(2, maps:to_list(AwaitingRel)), os:timestamp(), Session)
|
|
|
|
|
|
|
+ _ ->
|
|
|
|
|
+ AwaitingRel1 = lists:keysort(2, maps:to_list(AwaitingRel)),
|
|
|
|
|
+ expire_awaiting_rel(AwaitingRel1, os:timestamp(), Session)
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
expire_awaiting_rel([], _Now, Session) ->
|
|
expire_awaiting_rel([], _Now, Session) ->
|
|
|
- {ok, Session#session{await_rel_timer = undefined}};
|
|
|
|
|
|
|
+ {ok, Session};
|
|
|
|
|
|
|
|
expire_awaiting_rel([{PacketId, Ts} | More], Now,
|
|
expire_awaiting_rel([{PacketId, Ts} | More], Now,
|
|
|
Session = #session{awaiting_rel = AwaitingRel,
|
|
Session = #session{awaiting_rel = AwaitingRel,
|
|
@@ -693,7 +616,7 @@ expire_awaiting_rel([{PacketId, Ts} | More], Now,
|
|
|
Session1 = Session#session{awaiting_rel = maps:remove(PacketId, AwaitingRel)},
|
|
Session1 = Session#session{awaiting_rel = maps:remove(PacketId, AwaitingRel)},
|
|
|
expire_awaiting_rel(More, Now, Session1);
|
|
expire_awaiting_rel(More, Now, Session1);
|
|
|
Age ->
|
|
Age ->
|
|
|
- {ok, ensure_await_rel_timer(Timeout - max(0, Age), Session)}
|
|
|
|
|
|
|
+ {ok, Timeout - max(0, Age), Session}
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
%%--------------------------------------------------------------------
|
|
%%--------------------------------------------------------------------
|