Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor PubSub code to prepare for RDBMS #2122

Merged
merged 4 commits into from
Nov 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions include/pubsub.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,8 @@
%% of the current node. For example:
%% ```<<"/home/localhost/user">>'''</p>

-type(nodeIdx() :: pos_integer() | binary()).
-type(nodeIdx() :: pos_integer()).
%% @type nodeIdx() = integer() | binary().
%% note: pos_integer() should always be used, but we allow anything else coded
%% as binary, so one can have a custom implementation of nodetree with custom
%% indexing (see nodetree_virtual). this also allows to use any kind of key for
%% indexing nodes, as this can be usefull with external backends such as rdbms.

-type(itemId() :: binary()).
%% @type itemId() = string().
Expand Down
7 changes: 7 additions & 0 deletions src/jid.erl
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,16 @@ are_equal(_, _) ->
false.

%% @doc Returns true if `are_equal(to_bare(A), to_bare(B))'
-spec are_bare_equal(jid() | ljid(), jid() | ljid()) -> boolean().
are_bare_equal(#jid{luser = LUser, lserver = LServer},
#jid{luser = LUser, lserver = LServer}) ->
true;
are_bare_equal(#jid{luser = LUser, lserver = LServer}, {LUser, LServer, _}) ->
arcusfelis marked this conversation as resolved.
Show resolved Hide resolved
true;
are_bare_equal({LUser, LServer, _}, #jid{luser = LUser, lserver = LServer}) ->
true;
are_bare_equal({LUser, LServer, _}, {LUser, LServer, _}) ->
true;
are_bare_equal(_, _) ->
false.

Expand Down
2 changes: 1 addition & 1 deletion src/pubsub/gen_pubsub_node.erl
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@

-callback subscribe_node(NodeIdx :: nodeIdx(),
Sender :: jid:jid(),
Subscriber :: jid:jid(),
Subscriber :: jid:ljid(),
AccessModel :: accessModel(),
SendLast :: 'never' | 'on_sub' | 'on_sub_and_presence',
PresenceSubscription :: boolean(),
Expand Down
140 changes: 91 additions & 49 deletions src/pubsub/mod_pubsub.erl

Large diffs are not rendered by default.

97 changes: 92 additions & 5 deletions src/pubsub/mod_pubsub_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

-include("mongoose_logger.hrl").

-export([transaction_error/2, dirty_error/4]).

%%====================================================================
%% Behaviour callbacks
%%====================================================================
Expand All @@ -20,23 +22,33 @@

-callback stop() -> ok.

-callback transaction(Fun :: fun(() -> {result | error, any()})) ->
%% ----------------------- Fun execution ------------------------

%% `ErrorDebug` are the maps of extra data that will be added to error tuple

-callback transaction(Fun :: fun(() -> {result | error, any()}),
ErrorDebug :: map()) ->
{result | error, any()}.

%% Synchronous
-callback dirty(Fun :: fun(() -> {result | error, any()})) ->
-callback dirty(Fun :: fun(() -> {result | error, any()}),
ErrorDebug :: map()) ->
{result | error, any()}.

-callback set_state(State :: mod_pubsub:pubsubState()) -> ok.
%% ----------------------- Direct #pubsub_state access ------------------------

%% TODO: Replace with del_node when it is fully possible from backend
%% i.e. when pubsub_item is migrated to RDBMS as well
-callback del_state(Nidx :: mod_pubsub:nodeIdx(),
UserLJID :: jid:ljid()) -> ok.
LJID :: jid:ljid()) -> ok.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If other callbacks expect jid:jid type, can we make this one consistent with the other and expect jid:jid as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, because it is called only in one place, where only ljid() is accessible directly so I'd have to convert it to jid(). This function will be removed anyway as soon as pubsub_item table is migrated to RDBMS as well.


%% When a state is not found, returns empty state.
%% Maybe can be removed completely later?
-callback get_state(Nidx :: mod_pubsub:nodeIdx(),
UserLJID :: jid:ljid()) ->
JID :: jid:jid()) ->
{ok, mod_pubsub:pubsubState()}.

%% Maybe can be removed completely later?
-callback get_states(Nidx :: mod_pubsub:nodeIdx()) ->
{ok, [mod_pubsub:pubsubState()]}.

Expand All @@ -52,10 +64,85 @@
-callback get_own_nodes_states(JID :: jid:jid()) ->
{ok, [mod_pubsub:pubsubState()]}.

%% ----------------------- Affiliations ------------------------

-callback set_affiliation(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
Affiliation :: mod_pubsub:affiliation()) ->
ok.

-callback get_affiliation(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid()) ->
{ok, mod_pubsub:affiliation()}.

%% ----------------------- Subscriptions ------------------------

-callback add_subscription(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
Sub :: mod_pubsub:subscription(),
SubId :: mod_pubsub:subId()) ->
ok.

-callback update_subscription(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
Subscription :: mod_pubsub:subscription(),
SubId :: mod_pubsub:subId()) ->
ok.

-callback get_node_subscriptions(Nidx :: mod_pubsub:nodeIdx()) ->
{ok, [{Entity :: jid:jid(), Sub :: mod_pubsub:subscription(), SubId :: mod_pubsub:subId()}]}.

-callback get_node_entity_subscriptions(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid()) ->
{ok, [{Sub :: mod_pubsub:subscription(), SubId :: mod_pubsub:subId()}]}.

-callback delete_subscription(
Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
SubId :: mod_pubsub:subId()) ->
ok.

-callback delete_all_subscriptions(
Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid()) ->
ok.

%% ----------------------- Items ------------------------

%% TODO: Refactor to use MaxItems value, so separate remove_items in publishing
%% won't be necessary and the whole operation may be optimised in DB layer.
-callback add_item(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
ItemId :: mod_pubsub:itemId()) ->
ok.

-callback remove_items(Nidx :: mod_pubsub:nodeIdx(),
JID :: jid:jid(),
ItemIds :: [mod_pubsub:itemId()]) ->
ok.

-callback remove_all_items(Nidx :: mod_pubsub:nodeIdx()) ->
ok.

%%====================================================================
%% API
%%====================================================================

%% These are made as separate functions to make tracing easier, just in case.

-spec transaction_error(Reason :: any(), ErrorDebug :: map()) ->
{error, Details :: map()}.
transaction_error(Reason, ErrorDebug) ->
{error, ErrorDebug#{ event => transaction_failure,
reason => Reason }}.

-spec dirty_error(Class :: atom(), Reason :: any(), StackTrace :: list(), ErrorDebug :: map()) ->
{error, Details :: map()}.
dirty_error(Class, Reason, StackTrace, ErrorDebug) ->
{error, ErrorDebug#{ event => dirty_failure,
class => Class,
reason => Reason,
stacktrace => StackTrace}}.

%%====================================================================
%% Internal functions
Expand Down
Loading