]> granicus.if.org Git - ejabberd/commitdiff
Use new cache API in mod_shared_roster_ldap
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 21 Apr 2017 07:43:14 +0000 (10:43 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 21 Apr 2017 07:43:14 +0000 (10:43 +0300)
src/mod_shared_roster_ldap.erl

index feb1880b6267c7796062a52c64d88b2eefdce089..951ff073929392a2a7cc311d55d43700c2a187e4 100644 (file)
@@ -33,7 +33,7 @@
 -behaviour(gen_mod).
 
 %% API
--export([start/2, stop/1]).
+-export([start/2, stop/1, reload/3]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2,
@@ -41,7 +41,8 @@
 
 -export([get_user_roster/2, c2s_session_opened/1,
         get_jid_info/4, process_item/2, in_subscription/6,
-        out_subscription/4, mod_opt_type/1, opt_type/1, depends/2]).
+        out_subscription/4, mod_opt_type/1, opt_type/1, depends/2,
+        transform_module_options/1]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -50,9 +51,8 @@
 -include("eldap.hrl").
 
 -define(SETS, gb_sets).
--define(CACHE_SIZE, 1000).
--define(USER_CACHE_VALIDITY, 300).  %% in seconds
--define(GROUP_CACHE_VALIDITY, 300).
+-define(USER_CACHE, shared_roster_ldap_user_cache).
+-define(GROUP_CACHE, shared_roster_ldap_group_cache).
 -define(LDAP_SEARCH_TIMEOUT, 5).    %% Timeout for LDAP search queries in seconds
 -define(INVALID_SETTING_MSG, "~s is not properly set! ~s will not function.").
 
          ufilter = <<"">>                             :: binary(),
          rfilter = <<"">>                             :: binary(),
          gfilter = <<"">>                             :: binary(),
-        auth_check = true                            :: boolean(),
-         user_cache_size = ?CACHE_SIZE                :: non_neg_integer(),
-         group_cache_size = ?CACHE_SIZE               :: non_neg_integer(),
-        user_cache_validity = ?USER_CACHE_VALIDITY   :: non_neg_integer(),
-         group_cache_validity = ?GROUP_CACHE_VALIDITY :: non_neg_integer()}).
+        auth_check = true                            :: boolean()}).
 
 -record(group_info, {desc, members}).
 
@@ -96,6 +92,17 @@ start(Host, Opts) ->
 stop(Host) ->
     gen_mod:stop_child(?MODULE, Host).
 
+reload(Host, NewOpts, _OldOpts) ->
+    case init_cache(Host, NewOpts) of
+       true ->
+           ets_cache:setopts(?USER_CACHE, cache_opts(Host, NewOpts)),
+           ets_cache:setopts(?GROUP_CACHE, cache_opts(Host, NewOpts));
+       false ->
+           ok
+    end,
+    Proc = gen_mod:get_module_proc(Host, ?MODULE),
+    gen_server:cast(Proc, {set_state, parse_options(Host, NewOpts)}).
+
 depends(_Host, _Opts) ->
     [{mod_roster, hard}].
 
@@ -231,12 +238,7 @@ process_subscription(Direction, User, Server, JID,
 init([Host, Opts]) ->
     process_flag(trap_exit, true),
     State = parse_options(Host, Opts),
-    cache_tab:new(shared_roster_ldap_user,
-                 [{max_size, State#state.user_cache_size}, {lru, false},
-                  {life_time, State#state.user_cache_validity}]),
-    cache_tab:new(shared_roster_ldap_group,
-                 [{max_size, State#state.group_cache_size}, {lru, false},
-                  {life_time, State#state.group_cache_validity}]),
+    init_cache(Host, Opts),
     ejabberd_hooks:add(roster_get, Host, ?MODULE,
                       get_user_roster, 70),
     ejabberd_hooks:add(roster_in_subscription, Host,
@@ -260,6 +262,8 @@ handle_call(get_state, _From, State) ->
 handle_call(_Request, _From, State) ->
     {reply, {error, badarg}, State}.
 
+handle_cast({set_state, NewState}, _State) ->
+    {noreply, NewState};
 handle_cast(_Msg, State) -> {noreply, State}.
 
 handle_info(_Info, State) -> {noreply, State}.
@@ -341,9 +345,9 @@ get_user_displayed_groups({User, Host}) ->
 
 get_group_users(Host, Group) ->
     {ok, State} = eldap_utils:get_state(Host, ?MODULE),
-    case cache_tab:dirty_lookup(shared_roster_ldap_group,
-                               {Group, Host},
-                               fun () -> search_group_info(State, Group) end) of
+    case ets_cache:lookup(?GROUP_CACHE,
+                         {Group, Host},
+                         fun () -> search_group_info(State, Group) end) of
         {ok, #group_info{members = Members}}
          when Members /= undefined ->
             Members;
@@ -352,9 +356,9 @@ get_group_users(Host, Group) ->
 
 get_group_name(Host, Group) ->
     {ok, State} = eldap_utils:get_state(Host, ?MODULE),
-    case cache_tab:dirty_lookup(shared_roster_ldap_group,
-                               {Group, Host},
-                               fun () -> search_group_info(State, Group) end)
+    case ets_cache:lookup(?GROUP_CACHE,
+                         {Group, Host},
+                         fun () -> search_group_info(State, Group) end)
        of
       {ok, #group_info{desc = GroupName}}
          when GroupName /= undefined ->
@@ -364,9 +368,9 @@ get_group_name(Host, Group) ->
 
 get_user_name(User, Host) ->
     {ok, State} = eldap_utils:get_state(Host, ?MODULE),
-    case cache_tab:dirty_lookup(shared_roster_ldap_user,
-                               {User, Host},
-                               fun () -> search_user_name(State, User) end)
+    case ets_cache:lookup(?USER_CACHE,
+                         {User, Host},
+                         fun () -> search_user_name(State, User) end)
        of
       {ok, UserName} -> UserName;
       error -> User
@@ -494,22 +498,6 @@ parse_options(Host, Opts) ->
                                    (false) -> false;
                                    (true) -> true
                                 end, true),
-    UserCacheValidity = gen_mod:get_opt(
-                          {ldap_user_cache_validity, Host}, Opts,
-                          fun(I) when is_integer(I), I>0 -> I end,
-                          ?USER_CACHE_VALIDITY),
-    GroupCacheValidity = gen_mod:get_opt(
-                           {ldap_group_cache_validity, Host}, Opts,
-                           fun(I) when is_integer(I), I>0 -> I end,
-                           ?GROUP_CACHE_VALIDITY),
-    UserCacheSize = gen_mod:get_opt(
-                      {ldap_user_cache_size, Host}, Opts,
-                      fun(I) when is_integer(I), I>0 -> I end,
-                      ?CACHE_SIZE),
-    GroupCacheSize = gen_mod:get_opt(
-                       {ldap_group_cache_size, Host}, Opts,
-                       fun(I) when is_integer(I), I>0 -> I end,
-                       ?CACHE_SIZE),
     ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts,
                                        fun check_filter/1, <<"">>),
     ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts,
@@ -562,17 +550,67 @@ parse_options(Host, Opts) ->
           uid_format = UIDAttrFormat,
           uid_format_re = UIDAttrFormatRe, filter = Filter,
           ufilter = UserFilter, rfilter = RosterFilter,
-          gfilter = GroupFilter, auth_check = AuthCheck,
-          user_cache_size = UserCacheSize,
-          user_cache_validity = UserCacheValidity,
-          group_cache_size = GroupCacheSize,
-          group_cache_validity = GroupCacheValidity}.
+          gfilter = GroupFilter, auth_check = AuthCheck}.
 
 check_filter(F) ->
     NewF = iolist_to_binary(F),
     {ok, _} = eldap_filter:parse(NewF),
     NewF.
 
+init_cache(Host, Opts) ->
+    UseCache = use_cache(Host, Opts),
+    case UseCache of
+       true ->
+           CacheOpts = cache_opts(Host, Opts),
+           ets_cache:new(?USER_CACHE, CacheOpts),
+           ets_cache:new(?GROUP_CACHE, CacheOpts);
+       false ->
+           ets_cache:delete(?USER_CACHE),
+           ets_cache:delete(?GROUP_CACHE)
+    end,
+    UseCache.
+
+use_cache(Host, Opts) ->
+    gen_mod:get_opt(use_cache, Opts, mod_opt_type(use_cache),
+                   ejabberd_config:use_cache(Host)).
+
+cache_opts(Host, Opts) ->
+    MaxSize = gen_mod:get_opt(cache_size, Opts,
+                             mod_opt_type(cache_size),
+                             ejabberd_config:cache_size(Host)),
+    CacheMissed = gen_mod:get_opt(cache_missed, Opts,
+                                 mod_opt_type(cache_missed),
+                                 ejabberd_config:cache_missed(Host)),
+    LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
+                                   mod_opt_type(cache_life_time),
+                                   ejabberd_config:cache_life_time(Host)) of
+                  infinity -> infinity;
+                  I -> timer:seconds(I)
+              end,
+    [{max_size, MaxSize}, {cache_missed, CacheMissed}, {life_time, LifeTime}].
+
+transform_module_options(Opts) ->
+    lists:map(
+      fun({ldap_group_cache_size, I}) ->
+             ?WARNING_MSG("Option 'ldap_group_cache_size' is deprecated, "
+                          "use 'cache_size' instead", []),
+             {cache_size, I};
+        ({ldap_user_cache_size, I}) ->
+             ?WARNING_MSG("Option 'ldap_user_cache_size' is deprecated, "
+                          "use 'cache_size' instead", []),
+             {cache_size, I};
+        ({ldap_group_cache_validity, Secs}) ->
+             ?WARNING_MSG("Option 'ldap_group_cache_validity' is deprecated, "
+                          "use 'cache_life_time' instead", []),
+             {cache_life_time, Secs};
+        ({ldap_user_cache_validity, Secs}) ->
+             ?WARNING_MSG("Option 'ldap_user_cache_validity' is deprecated, "
+                          "use 'cache_life_time' instead", []),
+             {cache_life_time, Secs};
+        (Opt) ->
+             Opt
+      end, Opts).
+
 mod_opt_type(deref_aliases) ->
     fun (never) -> never;
        (searching) -> searching;
@@ -618,10 +656,13 @@ mod_opt_type(ldap_auth_check) ->
     end;
 mod_opt_type(ldap_filter) -> fun check_filter/1;
 mod_opt_type(ldap_gfilter) -> fun check_filter/1;
-mod_opt_type(ldap_group_cache_size) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
-mod_opt_type(ldap_group_cache_validity) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
+mod_opt_type(O) when O == cache_size;
+                    O == cache_life_time ->
+    fun (I) when is_integer(I), I > 0 -> I;
+       (infinity) -> infinity
+    end;
+mod_opt_type(O) when O == use_cache; O == cache_missed ->
+    fun (B) when is_boolean(B) -> B end;
 mod_opt_type(ldap_groupattr) -> fun iolist_to_binary/1;
 mod_opt_type(ldap_groupdesc) -> fun iolist_to_binary/1;
 mod_opt_type(ldap_memberattr) -> fun iolist_to_binary/1;
@@ -633,38 +674,22 @@ mod_opt_type(ldap_memberattr_format_re) ->
     end;
 mod_opt_type(ldap_rfilter) -> fun check_filter/1;
 mod_opt_type(ldap_ufilter) -> fun check_filter/1;
-mod_opt_type(ldap_user_cache_size) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
-mod_opt_type(ldap_user_cache_validity) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
 mod_opt_type(ldap_userdesc) -> fun iolist_to_binary/1;
 mod_opt_type(ldap_useruid) -> fun iolist_to_binary/1;
 mod_opt_type(_) ->
     [ldap_auth_check, ldap_filter, ldap_gfilter,
-     ldap_group_cache_size, ldap_group_cache_validity,
      ldap_groupattr, ldap_groupdesc, ldap_memberattr,
      ldap_memberattr_format, ldap_memberattr_format_re,
-     ldap_rfilter, ldap_ufilter, ldap_user_cache_size,
-     ldap_user_cache_validity, ldap_userdesc, ldap_useruid,
+     ldap_rfilter, ldap_ufilter, ldap_userdesc, ldap_useruid,
      deref_aliases, ldap_backups, ldap_base,
      ldap_deref_aliases, ldap_encrypt, ldap_password,
      ldap_port, ldap_rootdn, ldap_servers,
      ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth,
-     ldap_tls_verify].
+     ldap_tls_verify, use_cache, cache_missed, cache_size, cache_life_time].
 
 opt_type(ldap_filter) -> fun check_filter/1;
 opt_type(ldap_gfilter) -> fun check_filter/1;
-opt_type(ldap_group_cache_size) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
-opt_type(ldap_group_cache_validity) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
 opt_type(ldap_rfilter) -> fun check_filter/1;
 opt_type(ldap_ufilter) -> fun check_filter/1;
-opt_type(ldap_user_cache_size) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
-opt_type(ldap_user_cache_validity) ->
-    fun (I) when is_integer(I), I > 0 -> I end;
 opt_type(_) ->
-    [ldap_filter, ldap_gfilter, ldap_group_cache_size,
-     ldap_group_cache_validity, ldap_rfilter, ldap_ufilter,
-     ldap_user_cache_size, ldap_user_cache_validity].
+    [ldap_filter, ldap_gfilter, ldap_rfilter, ldap_ufilter].