mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
* src/mod_muc/mod_muc_room.erl: Clean user activity after timeout
(EJAB-804) SVN Revision: 1688
This commit is contained in:
parent
78b90e9300
commit
964cb84864
@ -1,3 +1,8 @@
|
||||
2008-11-28 Alexey Shchepin <alexey@process-one.net>
|
||||
|
||||
* src/mod_muc/mod_muc_room.erl: Clean user activity after timeout
|
||||
(EJAB-804)
|
||||
|
||||
2008-11-26 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/ejabberdctl.template: Fix detection of ejabberdctl.cfg path
|
||||
|
@ -103,7 +103,7 @@
|
||||
subject = "",
|
||||
subject_author = "",
|
||||
just_created = false,
|
||||
activity = ?DICT:new(),
|
||||
activity = treap:empty(),
|
||||
room_shaper,
|
||||
room_queue = queue:new()}).
|
||||
|
||||
@ -243,13 +243,12 @@ normal_state({route, From, "",
|
||||
message_time = Now,
|
||||
message_shaper = MessageShaper},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity),
|
||||
store_user_activity(
|
||||
From, NewActivity, StateData),
|
||||
StateData2 =
|
||||
StateData1#state{
|
||||
room_shaper = RoomShaper},
|
||||
process_groupchat_message(From, Packet, StateData1);
|
||||
process_groupchat_message(From, Packet, StateData2);
|
||||
true ->
|
||||
StateData1 =
|
||||
if
|
||||
@ -270,13 +269,12 @@ normal_state({route, From, "",
|
||||
{message, From},
|
||||
StateData#state.room_queue),
|
||||
StateData2 =
|
||||
StateData1#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity),
|
||||
store_user_activity(
|
||||
From, NewActivity, StateData1),
|
||||
StateData3 =
|
||||
StateData2#state{
|
||||
room_queue = RoomQueue},
|
||||
{next_state, normal_state, StateData2}
|
||||
{next_state, normal_state, StateData3}
|
||||
end;
|
||||
true ->
|
||||
MessageInterval =
|
||||
@ -290,11 +288,8 @@ normal_state({route, From, "",
|
||||
message = Packet,
|
||||
message_shaper = MessageShaper},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity)},
|
||||
store_user_activity(
|
||||
From, NewActivity, StateData),
|
||||
{next_state, normal_state, StateData1}
|
||||
end;
|
||||
"error" ->
|
||||
@ -436,12 +431,7 @@ normal_state({route, From, Nick,
|
||||
(Now >= Activity#activity.presence_time + MinPresenceInterval) and
|
||||
(Activity#activity.presence == undefined) ->
|
||||
NewActivity = Activity#activity{presence_time = Now},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity)},
|
||||
StateData1 = store_user_activity(From, NewActivity, StateData),
|
||||
process_presence(From, Nick, Packet, StateData1);
|
||||
true ->
|
||||
if
|
||||
@ -454,12 +444,7 @@ normal_state({route, From, Nick,
|
||||
ok
|
||||
end,
|
||||
NewActivity = Activity#activity{presence = {Nick, Packet}},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity)},
|
||||
StateData1 = store_user_activity(From, NewActivity, StateData),
|
||||
{next_state, normal_state, StateData1}
|
||||
end;
|
||||
|
||||
@ -737,27 +722,25 @@ handle_info(process_room_queue, normal_state = StateName, StateData) ->
|
||||
Packet = Activity#activity.message,
|
||||
NewActivity = Activity#activity{message = undefined},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity),
|
||||
store_user_activity(
|
||||
From, NewActivity, StateData),
|
||||
StateData2 =
|
||||
StateData1#state{
|
||||
room_queue = RoomQueue},
|
||||
StateData2 = prepare_room_queue(StateData1),
|
||||
process_groupchat_message(From, Packet, StateData2);
|
||||
StateData3 = prepare_room_queue(StateData2),
|
||||
process_groupchat_message(From, Packet, StateData3);
|
||||
{{value, {presence, From}}, RoomQueue} ->
|
||||
Activity = get_user_activity(From, StateData),
|
||||
{Nick, Packet} = Activity#activity.presence,
|
||||
NewActivity = Activity#activity{presence = undefined},
|
||||
StateData1 =
|
||||
StateData#state{
|
||||
activity = ?DICT:store(
|
||||
jlib:jid_tolower(From),
|
||||
NewActivity,
|
||||
StateData#state.activity),
|
||||
store_user_activity(
|
||||
From, NewActivity, StateData),
|
||||
StateData2 =
|
||||
StateData1#state{
|
||||
room_queue = RoomQueue},
|
||||
StateData2 = prepare_room_queue(StateData1),
|
||||
process_presence(From, Nick, Packet, StateData2);
|
||||
StateData3 = prepare_room_queue(StateData2),
|
||||
process_presence(From, Nick, Packet, StateData3);
|
||||
{empty, _} ->
|
||||
{next_state, StateName, StateData}
|
||||
end;
|
||||
@ -1284,9 +1267,9 @@ get_max_users_admin_threshold(StateData) ->
|
||||
mod_muc, max_users_admin_threshold, 5).
|
||||
|
||||
get_user_activity(JID, StateData) ->
|
||||
case ?DICT:find(jlib:jid_tolower(JID),
|
||||
StateData#state.activity) of
|
||||
{ok, A} -> A;
|
||||
case treap:lookup(jlib:jid_tolower(JID),
|
||||
StateData#state.activity) of
|
||||
{ok, _P, A} -> A;
|
||||
error ->
|
||||
MessageShaper =
|
||||
shaper:new(gen_mod:get_module_opt(
|
||||
@ -1300,6 +1283,82 @@ get_user_activity(JID, StateData) ->
|
||||
presence_shaper = PresenceShaper}
|
||||
end.
|
||||
|
||||
store_user_activity(JID, UserActivity, StateData) ->
|
||||
MinMessageInterval =
|
||||
gen_mod:get_module_opt(
|
||||
StateData#state.server_host,
|
||||
mod_muc, min_message_interval, 0),
|
||||
MinPresenceInterval =
|
||||
gen_mod:get_module_opt(
|
||||
StateData#state.server_host,
|
||||
mod_muc, min_presence_interval, 0),
|
||||
Key = jlib:jid_tolower(JID),
|
||||
Now = now_to_usec(now()),
|
||||
Activity1 = clean_treap(StateData#state.activity, {1, -Now}),
|
||||
Activity =
|
||||
case treap:lookup(Key, Activity1) of
|
||||
{ok, _P, _A} ->
|
||||
treap:delete(Key, Activity1);
|
||||
error ->
|
||||
Activity1
|
||||
end,
|
||||
StateData1 =
|
||||
case (MinMessageInterval == 0) andalso
|
||||
(MinPresenceInterval == 0) andalso
|
||||
(UserActivity#activity.message_shaper == none) andalso
|
||||
(UserActivity#activity.presence_shaper == none) andalso
|
||||
(UserActivity#activity.message == undefined) andalso
|
||||
(UserActivity#activity.presence == undefined) of
|
||||
true ->
|
||||
StateData#state{activity = Activity};
|
||||
false ->
|
||||
case (UserActivity#activity.message == undefined) andalso
|
||||
(UserActivity#activity.presence == undefined) of
|
||||
true ->
|
||||
{_, MessageShaperInterval} =
|
||||
shaper:update(UserActivity#activity.message_shaper,
|
||||
100000),
|
||||
{_, PresenceShaperInterval} =
|
||||
shaper:update(UserActivity#activity.presence_shaper,
|
||||
100000),
|
||||
Delay = lists:max([MessageShaperInterval,
|
||||
PresenceShaperInterval,
|
||||
MinMessageInterval * 1000,
|
||||
MinPresenceInterval * 1000]) * 1000,
|
||||
Priority = {1, -(Now + Delay)},
|
||||
StateData#state{
|
||||
activity = treap:insert(
|
||||
Key,
|
||||
Priority,
|
||||
UserActivity,
|
||||
Activity)};
|
||||
false ->
|
||||
Priority = {0, 0},
|
||||
StateData#state{
|
||||
activity = treap:insert(
|
||||
Key,
|
||||
Priority,
|
||||
UserActivity,
|
||||
Activity)}
|
||||
end
|
||||
end,
|
||||
StateData1.
|
||||
|
||||
clean_treap(Treap, CleanPriority) ->
|
||||
case treap:is_empty(Treap) of
|
||||
true ->
|
||||
Treap;
|
||||
false ->
|
||||
{_Key, Priority, _Value} = treap:get_root(Treap),
|
||||
if
|
||||
Priority > CleanPriority ->
|
||||
clean_treap(treap:delete_root(Treap), CleanPriority);
|
||||
true ->
|
||||
Treap
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
prepare_room_queue(StateData) ->
|
||||
case queue:out(StateData#state.room_queue) of
|
||||
{{value, {message, From}}, _RoomQueue} ->
|
||||
|
Loading…
Reference in New Issue
Block a user