mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Subsecond timestamp granularity in offline messages (EJAB-1376)
This commit is contained in:
parent
089a00fc3f
commit
caf64c035f
@ -157,9 +157,11 @@ i2b(L) when is_list(L) -> list_to_binary(L).
|
|||||||
%% Hours = integer()
|
%% Hours = integer()
|
||||||
%% Minutes = integer()
|
%% Minutes = integer()
|
||||||
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}, Timezone) ->
|
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}, Timezone) ->
|
||||||
|
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}, {milliseconds, 0}}, Timezone);
|
||||||
|
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}, {_SubsecondUnit, SubsecondValue}}, Timezone) ->
|
||||||
Timestamp_string = lists:flatten(
|
Timestamp_string = lists:flatten(
|
||||||
io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w",
|
io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w.~3..0w",
|
||||||
[Year, Month, Day, Hour, Minute, Second])),
|
[Year, Month, Day, Hour, Minute, Second, SubsecondValue])),
|
||||||
Timezone_string = case Timezone of
|
Timezone_string = case Timezone of
|
||||||
utc -> "Z";
|
utc -> "Z";
|
||||||
{Sign, {TZh, TZm}} ->
|
{Sign, {TZh, TZm}} ->
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
|
|
||||||
%%% Database schema (version / storage / table)
|
%%% Database schema (version / storage / table)
|
||||||
%%%
|
%%%
|
||||||
|
%%% In this module, timestamp is the timestamp expressed in milliseconds.
|
||||||
|
%%% in jlib.erl, the timestamp is a tuple {{Y,M,D},{H,M,S}} or {{Y,M,D},{H,M,S},{Unit,Value}
|
||||||
|
%%% where Unit = milliseconds
|
||||||
|
%%% and Value = integer() in the proper unit
|
||||||
|
%%%
|
||||||
%%% 2.1.x / mnesia / offline_msg
|
%%% 2.1.x / mnesia / offline_msg
|
||||||
%%% us = {Username::string(), Host::string()}
|
%%% us = {Username::string(), Host::string()}
|
||||||
%%% timestamp = now()
|
%%% timestamp = now()
|
||||||
@ -348,22 +353,15 @@ resend_offline_messages(User, Server) ->
|
|||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(R) ->
|
fun(R) ->
|
||||||
Packet = R#offline_msg.packet,
|
Packet = R#offline_msg.packet,
|
||||||
|
TimeXml = timestamp_to_xml(R#offline_msg.timestamp, Server),
|
||||||
|
TimeXml91 = timestamp_to_xml(R#offline_msg.timestamp),
|
||||||
ejabberd_sm !
|
ejabberd_sm !
|
||||||
{route,
|
{route,
|
||||||
R#offline_msg.from,
|
R#offline_msg.from,
|
||||||
R#offline_msg.to,
|
R#offline_msg.to,
|
||||||
exmpp_xml:append_children(
|
exmpp_xml:append_children(
|
||||||
Packet,
|
Packet,
|
||||||
[jlib:timestamp_to_xml(
|
[TimeXml, TimeXml91]
|
||||||
calendar:now_to_universal_time(R#offline_msg.timestamp),
|
|
||||||
utc,
|
|
||||||
exmpp_jid:make("", Server, ""),
|
|
||||||
"Offline Storage"),
|
|
||||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
|
||||||
jlib:timestamp_to_xml(
|
|
||||||
calendar:now_to_universal_time(
|
|
||||||
R#offline_msg.timestamp))
|
|
||||||
]
|
|
||||||
)}
|
)}
|
||||||
end,
|
end,
|
||||||
lists:keysort(#offline_msg.timestamp, Rs));
|
lists:keysort(#offline_msg.timestamp, Rs));
|
||||||
@ -392,21 +390,14 @@ pop_offline_messages(Ls, User, Server)
|
|||||||
Ls ++ lists:map(
|
Ls ++ lists:map(
|
||||||
fun(R) ->
|
fun(R) ->
|
||||||
[Packet] = exmpp_xml:parse_document(R#offline_msg.packet),
|
[Packet] = exmpp_xml:parse_document(R#offline_msg.packet),
|
||||||
|
TimeXml = timestamp_to_xml(R#offline_msg.timestamp, Server),
|
||||||
|
TimeXml91 = timestamp_to_xml(R#offline_msg.timestamp),
|
||||||
{route,
|
{route,
|
||||||
R#offline_msg.from,
|
R#offline_msg.from,
|
||||||
R#offline_msg.to,
|
R#offline_msg.to,
|
||||||
exmpp_xml:append_children(
|
exmpp_xml:append_children(
|
||||||
Packet,
|
Packet,
|
||||||
[jlib:timestamp_to_xml(
|
[TimeXml, TimeXml91]
|
||||||
calendar:now_to_universal_time(
|
|
||||||
timestamp_to_now(R#offline_msg.timestamp)),
|
|
||||||
utc,
|
|
||||||
exmpp_jid:make("", Server, ""),
|
|
||||||
"Offline Storage"),
|
|
||||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
|
||||||
jlib:timestamp_to_xml(
|
|
||||||
calendar:now_to_universal_time(
|
|
||||||
timestamp_to_now(R#offline_msg.timestamp)))]
|
|
||||||
)}
|
)}
|
||||||
end,
|
end,
|
||||||
lists:filter(
|
lists:filter(
|
||||||
@ -443,7 +434,7 @@ remove_expired_messages() ->
|
|||||||
end, gen_storage:all_table_hosts(offline_msg)).
|
end, gen_storage:all_table_hosts(offline_msg)).
|
||||||
|
|
||||||
remove_old_messages(Days) ->
|
remove_old_messages(Days) ->
|
||||||
Timestamp = make_timestamp() - 60 * 60 * 24 * Days,
|
Timestamp = make_timestamp() - 1000 * 60 * 60 * 24 * Days,
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(HostB) ->
|
fun(HostB) ->
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
@ -477,7 +468,7 @@ update_table(Host, mnesia) ->
|
|||||||
%% but its position in the erlang record is the same,
|
%% but its position in the erlang record is the same,
|
||||||
%% so we can refer to it using the new field name 'user_host'.
|
%% so we can refer to it using the new field name 'user_host'.
|
||||||
fun(#offline_msg{user_host = {US_U, US_S},
|
fun(#offline_msg{user_host = {US_U, US_S},
|
||||||
timestamp = {TsMegaSecs, TsSecs, _TsMicroSecs},
|
timestamp = {TsMegaSecs, TsSecs, TsMicroSecs},
|
||||||
expire = Expire,
|
expire = Expire,
|
||||||
from = From,
|
from = From,
|
||||||
to = To,
|
to = To,
|
||||||
@ -497,7 +488,7 @@ update_table(Host, mnesia) ->
|
|||||||
Packet, [?DEFAULT_NS], ?PREFIXED_NS),
|
Packet, [?DEFAULT_NS], ?PREFIXED_NS),
|
||||||
Packet1 = exmpp_xml:document_to_list(PacketXmlel),
|
Packet1 = exmpp_xml:document_to_list(PacketXmlel),
|
||||||
OM#offline_msg{user_host = {US_U1, US_S1},
|
OM#offline_msg{user_host = {US_U1, US_S1},
|
||||||
timestamp = TsMegaSecs * 1000000 + TsSecs,
|
timestamp = TsMegaSecs * 1000000000 + TsSecs * 1000 + TsMicroSecs div 1000,
|
||||||
expire = Expire1,
|
expire = Expire1,
|
||||||
from = From1,
|
from = From1,
|
||||||
to = To1,
|
to = To1,
|
||||||
@ -526,14 +517,39 @@ update_table(Host, odbc) ->
|
|||||||
convert_jid_to_exmpp("") -> undefined;
|
convert_jid_to_exmpp("") -> undefined;
|
||||||
convert_jid_to_exmpp(V) -> V.
|
convert_jid_to_exmpp(V) -> V.
|
||||||
|
|
||||||
|
%% Return the current timestamp in milliseconds
|
||||||
make_timestamp() ->
|
make_timestamp() ->
|
||||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
{MegaSecs, Secs, MicroSecs} = now(),
|
||||||
MegaSecs * 1000000 + Secs.
|
MegaSecs * 1000000000 + Secs * 1000 + MicroSecs div 1000.
|
||||||
|
|
||||||
timestamp_to_now(Timestamp) ->
|
timestamp_to_now(Timestamp) ->
|
||||||
MegaSecs = Timestamp div 1000000,
|
MegaSecs = Timestamp div 1000000000,
|
||||||
Secs = Timestamp rem 1000000,
|
Secs = (Timestamp rem 1000000000) div 1000,
|
||||||
{MegaSecs, Secs, 0}.
|
MicroSecs = (Timestamp rem 1000) * 1000,
|
||||||
|
{MegaSecs, Secs, MicroSecs}.
|
||||||
|
|
||||||
|
timestamp_to_isostring(Timestamp) ->
|
||||||
|
{Date, Time} = calendar:now_to_universal_time(timestamp_to_now(Timestamp)),
|
||||||
|
Milliseconds = (Timestamp rem 1000),
|
||||||
|
UniversalTimeSubsecond = {Date, Time, {milliseconds, Milliseconds}},
|
||||||
|
{TimeStr, ZoneStr} = jlib:timestamp_to_iso(UniversalTimeSubsecond, utc),
|
||||||
|
TimeStr ++ ZoneStr.
|
||||||
|
|
||||||
|
timestamp_to_xml(Timestamp, Server) ->
|
||||||
|
{Date, Time} = calendar:now_to_universal_time(timestamp_to_now(Timestamp)),
|
||||||
|
Milliseconds = (Timestamp rem 1000),
|
||||||
|
UniversalTimeSubsecond = {Date, Time, {milliseconds, Milliseconds}},
|
||||||
|
jlib:timestamp_to_xml(
|
||||||
|
UniversalTimeSubsecond,
|
||||||
|
utc,
|
||||||
|
exmpp_jid:make("", Server, ""),
|
||||||
|
"Offline Storage").
|
||||||
|
|
||||||
|
%% TODO: Delete once XEP-0091 is Obsolete
|
||||||
|
timestamp_to_xml(Timestamp) ->
|
||||||
|
jlib:timestamp_to_xml(
|
||||||
|
calendar:now_to_universal_time(
|
||||||
|
timestamp_to_now(Timestamp))).
|
||||||
|
|
||||||
find_x_timestamp([]) ->
|
find_x_timestamp([]) ->
|
||||||
make_timestamp();
|
make_timestamp();
|
||||||
@ -544,7 +560,7 @@ find_x_timestamp([#xmlel{ns = ?NS_DELAY} = El | Els]) ->
|
|||||||
Stamp = exmpp_xml:get_attribute_as_list(El, <<"stamp">>, ""),
|
Stamp = exmpp_xml:get_attribute_as_list(El, <<"stamp">>, ""),
|
||||||
case jlib:datetime_string_to_timestamp(Stamp) of
|
case jlib:datetime_string_to_timestamp(Stamp) of
|
||||||
undefined -> find_x_timestamp(Els);
|
undefined -> find_x_timestamp(Els);
|
||||||
{MegaSecs, Secs, _MicroSecs} -> MegaSecs * 1000000 + Secs
|
{MegaSecs, Secs, _MicroSecs} -> MegaSecs * 1000000000 + Secs * 1000
|
||||||
end;
|
end;
|
||||||
find_x_timestamp([_ | Els]) ->
|
find_x_timestamp([_ | Els]) ->
|
||||||
find_x_timestamp(Els).
|
find_x_timestamp(Els).
|
||||||
@ -597,12 +613,7 @@ user_queue(User, Server, Query, Lang) ->
|
|||||||
fun(#offline_msg{timestamp = TimeStamp, from = From, to = To,
|
fun(#offline_msg{timestamp = TimeStamp, from = From, to = To,
|
||||||
packet = PacketInitialString} = Msg) ->
|
packet = PacketInitialString} = Msg) ->
|
||||||
ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))),
|
ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))),
|
||||||
{{Year, Month, Day}, {Hour, Minute, Second}} =
|
Time = timestamp_to_isostring(TimeStamp),
|
||||||
calendar:now_to_local_time(timestamp_to_now(TimeStamp)),
|
|
||||||
Time = lists:flatten(
|
|
||||||
io_lib:format(
|
|
||||||
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
|
|
||||||
[Year, Month, Day, Hour, Minute, Second])),
|
|
||||||
SFrom = exmpp_jid:to_list(From),
|
SFrom = exmpp_jid:to_list(From),
|
||||||
STo = exmpp_jid:to_list(To),
|
STo = exmpp_jid:to_list(To),
|
||||||
[Packet] = exmpp_xmlstream:parse_element(PacketInitialString),
|
[Packet] = exmpp_xmlstream:parse_element(PacketInitialString),
|
||||||
@ -698,7 +709,8 @@ get_messages_subset2(Max, Length, MsgsAll) ->
|
|||||||
{MsgsFirstN, Msgs2} = lists:split(FirstN, MsgsAll),
|
{MsgsFirstN, Msgs2} = lists:split(FirstN, MsgsAll),
|
||||||
MsgsLastN = lists:nthtail(Length - FirstN - FirstN, Msgs2),
|
MsgsLastN = lists:nthtail(Length - FirstN - FirstN, Msgs2),
|
||||||
NoJID = exmpp_jid:make("...", "...", ""),
|
NoJID = exmpp_jid:make("...", "...", ""),
|
||||||
IntermediateMsg = #offline_msg{timestamp = now(), from = NoJID, to = NoJID,
|
TimeStamp = make_timestamp(),
|
||||||
|
IntermediateMsg = #offline_msg{timestamp = TimeStamp, from = NoJID, to = NoJID,
|
||||||
packet = exmpp_xml:element("...")},
|
packet = exmpp_xml:element("...")},
|
||||||
MsgsFirstN ++ [IntermediateMsg] ++ MsgsLastN.
|
MsgsFirstN ++ [IntermediateMsg] ++ MsgsLastN.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user