This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch wh/connect_to
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/wh/connect_to by this push:
     new 904040b27 cache the parsed config
904040b27 is described below

commit 904040b27faafea7d280a8383de267d3a733f722
Author: Will Holley <[email protected]>
AuthorDate: Tue May 5 13:59:06 2026 +0100

    cache the parsed config
    
    Cached the parsed dns_overrides configuration.
    I did consider adding per-connection caching as
    well, but this seemed to be of limited benefit
    in microbenchmarks. Adding the persistent_term
    cache yields approx a 3x performance improvement
    in resolution time (amounts to 150ms over
    10k resolutions on my machine).
---
 src/couch_replicator/priv/stats_descriptions.cfg   |  4 +++
 src/couch_replicator/src/couch_replicator_dns.erl  | 29 ++++++++++++++++++----
 .../src/couch_replicator_scheduler.erl             |  4 +++
 .../eunit/couch_replicator_dns_override_tests.erl  |  3 +++
 .../test/eunit/couch_replicator_dns_tests.erl      |  3 ++-
 5 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/src/couch_replicator/priv/stats_descriptions.cfg 
b/src/couch_replicator/priv/stats_descriptions.cfg
index 7edc87941..f7059e541 100644
--- a/src/couch_replicator/priv/stats_descriptions.cfg
+++ b/src/couch_replicator/priv/stats_descriptions.cfg
@@ -142,3 +142,7 @@
     {type, counter},
     {desc, <<"number of times a worker is gracefully shut down">>}
 ]}.
+{[couch_replicator, dns_overrides_applied], [
+    {type, counter},
+    {desc, <<"number of times DNS overrides were applied to replication 
requests">>}
+]}.
diff --git a/src/couch_replicator/src/couch_replicator_dns.erl 
b/src/couch_replicator/src/couch_replicator_dns.erl
index 9ff842b0e..7af377655 100644
--- a/src/couch_replicator/src/couch_replicator_dns.erl
+++ b/src/couch_replicator/src/couch_replicator_dns.erl
@@ -15,6 +15,7 @@
 -include_lib("ibrowse/include/ibrowse.hrl").
 
 -export([
+    init/0,
     resolve_host/1,
     apply_dns_override/2,
     add_sni_option/2,
@@ -31,6 +32,19 @@
 
 -type dns_override() :: {binary(), binary()}.
 
+-define(DNS_OVERRIDES_KEY, {?MODULE, dns_overrides}).
+
+%% Initialize DNS overrides cache
+-spec init() -> ok.
+init() ->
+    Overrides =
+        case config:get("replicator", "dns_overrides", undefined) of
+            undefined -> [];
+            ConfigStr -> parse_config(ConfigStr)
+        end,
+    persistent_term:put(?DNS_OVERRIDES_KEY, Overrides),
+    ok.
+
 -spec resolve_host(string()) -> {string(), string() | undefined}.
 resolve_host(Host) ->
     case find_override(list_to_binary(Host), get_overrides()) of
@@ -42,11 +56,15 @@ resolve_host(Host) ->
 
 -spec get_overrides() -> [dns_override()].
 get_overrides() ->
-    case config:get("replicator", "dns_overrides", undefined) of
-        undefined ->
-            [];
-        ConfigStr ->
-            parse_config(ConfigStr)
+    try
+        persistent_term:get(?DNS_OVERRIDES_KEY, [])
+    catch
+        error:badarg ->
+            % not initialized yet, fall back to reading config
+            case config:get("replicator", "dns_overrides", undefined) of
+                undefined -> [];
+                ConfigStr -> parse_config(ConfigStr)
+            end
     end.
 
 -spec parse_config(string()) -> [dns_override()].
@@ -168,6 +186,7 @@ apply_override_options(Opts, Protocol, TargetHost, 
OriginalHost) ->
         "DNS override (~p): ~s -> ~s",
         [Protocol, OriginalHost, TargetHost]
     ),
+    couch_stats:increment_counter([couch_replicator, dns_overrides_applied]),
     % Add connect_to option
     Opts1 = [{connect_to, TargetHost} | Opts],
     % Add SNI for HTTPS if OriginalHost is a hostname (not IP)
diff --git a/src/couch_replicator/src/couch_replicator_scheduler.erl 
b/src/couch_replicator/src/couch_replicator_scheduler.erl
index 9eb0b4723..eae1a321d 100644
--- a/src/couch_replicator/src/couch_replicator_scheduler.erl
+++ b/src/couch_replicator/src/couch_replicator_scheduler.erl
@@ -229,6 +229,7 @@ init(_) ->
     ],
     ?MODULE = ets:new(?MODULE, EtsOpts),
     ok = couch_replicator_share:init(),
+    ok = couch_replicator_dns:init(),
     ok = config:listen_for_changes(?MODULE, nil),
     Interval = get_interval_msec(),
     MaxJobs = config:get_integer("replicator", "max_jobs", ?DEFAULT_MAX_JOBS),
@@ -385,6 +386,9 @@ handle_config_change("replicator", "interval", V, _, S) ->
 handle_config_change("replicator", "max_history", V, _, S) ->
     ok = gen_server:cast(?MODULE, {set_max_history, list_to_integer(V)}),
     {ok, S};
+handle_config_change("replicator", "dns_overrides", _, _, S) ->
+    ok = couch_replicator_dns:init(),
+    {ok, S};
 handle_config_change("replicator.shares", Key, deleted, _, S) ->
     ok = gen_server:cast(?MODULE, {reset_shares, list_to_binary(Key)}),
     {ok, S};
diff --git 
a/src/couch_replicator/test/eunit/couch_replicator_dns_override_tests.erl 
b/src/couch_replicator/test/eunit/couch_replicator_dns_override_tests.erl
index 677f8b6fd..bc3844544 100644
--- a/src/couch_replicator/test/eunit/couch_replicator_dns_override_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_dns_override_tests.erl
@@ -46,6 +46,9 @@ should_replicate_with_dns_override({_Ctx, {Source, Target}}) 
->
     OverrideConfig = "example.com:" ++ SourceHost,
     config:set("replicator", "dns_overrides", OverrideConfig, false),
 
+    % reinitialize DNS cache to pick up the new config
+    couch_replicator_dns:init(),
+
     % replace source host with example.com
     OverrideUrl = re:replace(SourceUrl, SourceHost, "example.com", [{return, 
binary}]),
 
diff --git a/src/couch_replicator/test/eunit/couch_replicator_dns_tests.erl 
b/src/couch_replicator/test/eunit/couch_replicator_dns_tests.erl
index db23d2b5b..c40500b10 100644
--- a/src/couch_replicator/test/eunit/couch_replicator_dns_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_dns_tests.erl
@@ -114,7 +114,8 @@ resolve_host_test_() ->
                     "*.example.test:proxy.internal,foo.bar.com:127.0.0.1";
                 (_, _, Default) ->
                     Default
-            end)
+            end),
+            couch_replicator_dns:init()
         end,
         fun(_) ->
             meck:unload(config)

Reply via email to