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

Run hooks with a default (empty) accumulator #1156

Merged
merged 5 commits into from Jan 31, 2017
Merged

Run hooks with a default (empty) accumulator #1156

merged 5 commits into from Jan 31, 2017

Conversation

bartekgorny
Copy link
Collaborator

Simple modification resulting in plenty of code changes: all hook handers which were runned before (not run_folded) are now prepared to accept an accumulator, and return it, mostly unchanged. If called by 'run', the accumulator is an empty map, and return value is ignored.

By doing this, we make all handlers ready to switch to run_fold with a map-like accumulator, which will be subject of further PRs.

run1([{_Seq, Module, Function} | Ls], Hook, Args) ->
run1([], _Hook, Acc, _Args) ->
Acc;
run1([{_Seq, Module, Function} | Ls], Hook, Acc, Args) ->
Res = if is_function(Function) ->

Choose a reason for hiding this comment

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

According to Elvis:

Replace the 'if' expression on line 234 with a 'case' expression or function clauses.

LUser = jid:nodeprep(User),
LServer = jid:nameprep(Server),
?BACKEND:remove_user(LUser, LServer).
case ?BACKEND:remove_user(LUser, LServer) of

Choose a reason for hiding this comment

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

According to Elvis:

Don't use macros (like BACKEND on line 253) as module names.

#xmlel{name = <<"presence">>, attrs = Attrs,
children = Els} = Pkt) ->
children = Els}) ->
Type = xml:get_attr_s(<<"type">>, Attrs),
IsRemote = not lists:member(From#jid.lserver, ?MYHOSTS),
if IsRemote and

Choose a reason for hiding this comment

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

According to Elvis:

Replace the 'if' expression on line 171 with a 'case' expression or function clauses.

remove_user(Acc, User, Server) ->
remove_user(User, Server),
Acc.

remove_user(User, Server) ->
?BACKEND:remove_user(User, Server).

Choose a reason for hiding this comment

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

According to Elvis:

Don't use macros (like BACKEND on line 544) as module names.

node_cleanup(Node) ->
?BOSH_BACKEND:node_cleanup(Node).
node_cleanup(Acc, Node) ->
Res = ?BOSH_BACKEND:node_cleanup(Node),

Choose a reason for hiding this comment

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

According to Elvis:

Don't use macros (like BOSH_BACKEND on line 139) as module names.

@@ -31,15 +31,16 @@ stop(Host) ->
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, on_user_send_packet, 100),
ok.

on_user_send_packet(From, To, Packet) ->
on_user_send_packet(Acc, From, To, Packet) ->
Body = exml_query:path(Packet, [{element, <<"body">>}, cdata], <<>>),
Mod = get_callback_module(),
case Mod:should_make_req(Packet, From, To) of

Choose a reason for hiding this comment

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

According to Elvis:

Remove the dynamic function call on line 37. Only modules that define callbacks should make dynamic calls.

@@ -223,11 +223,14 @@ get_last(LUser, LServer) ->
count_active_users(LServer, Timestamp) ->
?BACKEND:count_active_users(LServer, Timestamp).

Choose a reason for hiding this comment

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

According to Elvis:

Don't use macros (like BACKEND on line 224) as module names.

#jid{luser = User, lserver = Server,
lresource = <<"">>},
#xmlel{name = <<"presence">>, attrs = Attrs,
children = Els} = Pkt) ->
children = Els}) ->
Type = xml:get_attr_s(<<"type">>, Attrs),
if Type == <<"">>; Type == <<"available">> ->

Choose a reason for hiding this comment

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

According to Elvis:

Replace the 'if' expression on line 154 with a 'case' expression or function clauses.

node_cleanup(Node) ->
?BOSH_BACKEND:node_cleanup(Node).
node_cleanup(Acc, Node) ->
Res = ?BOSH_BACKEND:node_cleanup(Node),

Choose a reason for hiding this comment

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

According to Elvis:

Remove the dynamic function call on line 139. Only modules that define callbacks should make dynamic calls.

@@ -533,6 +535,11 @@ remove_old_messages(Host, Days) ->
Timestamp = fallback_timestamp(Days, os:timestamp()),
?BACKEND:remove_old_messages(Host, Timestamp).

Choose a reason for hiding this comment

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

According to Elvis:

Don't use macros (like BACKEND on line 536) as module names.

@michalwski
Copy link
Contributor

As already agreed hook node_cleanup doesn't need special accumulator. I think It's enough if this hook's handler returns the value without putting it into a map.

@bartekgorny
Copy link
Collaborator Author

Actually, it was not on the list. But you're right, I'll rewrite it.

@@ -111,7 +111,7 @@ run(Hook, Host, Args) ->
case ets:lookup(hooks, {Hook, Host}) of
[{_, Ls}] ->
mongoose_metrics:increment_generic_hook_metric(Host, Hook),
run1(Ls, Hook, Args);
run1(Ls, Hook, #{}, Args); % run with empty map as accumulator
Copy link
Contributor

Choose a reason for hiding this comment

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

What stops us from calling run_fold1 here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

absolutely nothing :)

@@ -19,8 +19,8 @@
IsSimple :: boolean()) -> {ok, mod_mam:lookup_result()}
| {error, 'policy-violation'}.

-callback remove_archive(Host :: ejabberd:server(),
ArchiveID :: mod_mam:archive_id(), ArchiveJID :: ejabberd:jid()) -> 'ok'.
-callback remove_archive(Accc :: map(), Host :: ejabberd:server(),
Copy link
Member

Choose a reason for hiding this comment

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

Typo

@@ -111,7 +111,7 @@ run(Hook, Host, Args) ->
case ets:lookup(hooks, {Hook, Host}) of
[{_, Ls}] ->
mongoose_metrics:increment_generic_hook_metric(Host, Hook),
run1(Ls, Hook, Args);
run_fold1(Ls, Hook, #{}, Args); % run with empty map as accumulator
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be better to replace whole function body with run_fold(Hook, Host, #{}, Args).

on_presence_update(LUser, LServer, LResource, <<>>).
session_cleanup(Acc, LUser, LServer, LResource, _SID) ->
case on_presence_update(Acc, LUser, LServer, LResource, <<>>) of
Acc when is_map(Acc) -> Acc;
Copy link
Member

Choose a reason for hiding this comment

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

Why is_map is needed here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

True, it is stupid. It went away in one of the next commits which did not end up in this PR.

@@ -145,7 +145,7 @@ pop_msg(Key, LUser, LServer, To) ->
MD = riakc_obj:get_update_metadata(Obj),
[Timestamp] = riakc_obj:get_secondary_index(MD, ?TIMESTAMP_IDX),
[Expire] = riakc_obj:get_secondary_index(MD, ?EXPIRE_IDX),
User = riakc_obj:get_secondary_index(MD, ?USER_IDX),
%% User = riakc_obj:get_secondary_index(MD, ?USER_IDX),
Copy link
Member

Choose a reason for hiding this comment

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

If it's not used, kill it with fire.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As above.

@@ -122,7 +123,7 @@ start(Host, Opts) ->
remove_privacy_list, replace_privacy_list,
get_default_list]),
?BACKEND:init(Host, Opts),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
%% IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
Copy link
Member

Choose a reason for hiding this comment

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

Kill it with fire too. Here or in another PR, as it's not directly related to foldifying hooks.

[AdminU, AdminS, AdminP] = escalus_users:get_usp(Config, AdminSpec),

ok = escalus_ejabberd:rpc(ejabberd_auth, try_register, [AdminU, AdminS, AdminP]),
escalus_ejabberd:rpc(ejabberd_auth, try_register, [AdminU, AdminS, AdminP]),
Copy link
Member

Choose a reason for hiding this comment

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

Why have you removed the match for success?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was temporary - later commits introduced mongoose_stanza:to_map/1 which allows to check whether the return was correct, so those two lines because:

Res = escalus_ejabberd:rpc...
#{} = mongoose_stanza:to_map(Res)

{error, exists} ->
String = io_lib:format("User ~s@~s already registered at node ~p",
[User, Host, node()]),
{exists, String};
{error, Reason} ->
String = io_lib:format("Can't register user ~s@~s at node ~p: ~p",
[User, Host, node(), Reason]),
{cannot_register, String}
{cannot_register, String};
_ ->
Copy link
Member

Choose a reason for hiding this comment

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

I would avoid matching on everything here.

{error, exists} ->
String = io_lib:format("User ~s@~s already registered at node ~p",
[User, Host, node()]),
throw({exists, String});
{error, Reason} ->
String = io_lib:format("Can't register user ~s@~s at node ~p: ~p",
[User, Host, node(), Reason]),
throw({error, String})
throw({error, String});
_ ->
Copy link
Member

Choose a reason for hiding this comment

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

I would avoid matching on everything here.

{error, ?ERR_NOT_ACCEPTABLE}
end
end;
_ ->
Copy link
Member

Choose a reason for hiding this comment

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

I would avoid matching on everything here.

@@ -2068,7 +2068,7 @@ check_user_exist(Config) ->
%% when
[{_, AdminSpec}] = escalus_users:get_users([admin]),
[AdminU, AdminS, AdminP] = escalus_users:get_usp(Config, AdminSpec),
ok = escalus_ejabberd:rpc(ejabberd_auth, try_register, [AdminU, AdminS, AdminP]),
#{} = escalus_ejabberd:rpc(ejabberd_auth, try_register, [AdminU, AdminS, AdminP]),
Copy link
Member

Choose a reason for hiding this comment

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

I think ejabberd_auth:try_register returning an empty map on success is not very intuitive, especially it's not a hook on the outside. Internal hook usage leaks outside the scope of the function now. :(

@@ -200,13 +200,13 @@ get_prefs({GlobalDefaultMode, _, _}, _Host, _UserID, UserJID) ->

-spec remove_archive(ejabberd:server(), mod_mam:archive_id(),

Choose a reason for hiding this comment

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

According to Compiler:

spec for undefined function remove_archive/3

@gadgetci
Copy link

compiler failed with exit status: 1

@@ -200,13 +200,13 @@ get_prefs({GlobalDefaultMode, _, _}, _Host, _UserID, UserJID) ->

-spec remove_archive(ejabberd:server(), mod_mam:archive_id(),

Choose a reason for hiding this comment

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

According to Compiler:

spec for undefined function remove_archive/3

@michalwski
Copy link
Contributor

@fenek Could you make final review? You requested some changes, most of them were addressed by @bartekgorny

@fenek
Copy link
Member

fenek commented Jan 30, 2017

Well, now it requires rebasing. :( Sorry for the delay but sickness was merciless.

@bartekgorny bartekgorny reopened this Jan 31, 2017
@fenek fenek merged commit 57f0701 into master Jan 31, 2017
@fenek fenek deleted the accum-run branch January 31, 2017 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants