summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--distro/pkg/deb/knot-resolver-core.install1
-rw-r--r--distro/pkg/rpm/knot-resolver.spec1
-rw-r--r--modules/meson.build1
-rw-r--r--modules/prefetch/README.rst18
-rw-r--r--modules/prefetch/prefetch.lua21
5 files changed, 42 insertions, 0 deletions
diff --git a/distro/pkg/deb/knot-resolver-core.install b/distro/pkg/deb/knot-resolver-core.install
index 74ff1c57..1e57ac9b 100644
--- a/distro/pkg/deb/knot-resolver-core.install
+++ b/distro/pkg/deb/knot-resolver-core.install
@@ -18,6 +18,7 @@ usr/lib/knot-resolver/kres_modules/experimental_dot_auth.lua
usr/lib/knot-resolver/kres_modules/graphite.lua
usr/lib/knot-resolver/kres_modules/policy.lua
usr/lib/knot-resolver/kres_modules/predict.lua
+usr/lib/knot-resolver/kres_modules/prefetch.lua
usr/lib/knot-resolver/kres_modules/prefill.lua
usr/lib/knot-resolver/kres_modules/priming.lua
usr/lib/knot-resolver/kres_modules/rebinding.lua
diff --git a/distro/pkg/rpm/knot-resolver.spec b/distro/pkg/rpm/knot-resolver.spec
index acf313f8..5fd08f8d 100644
--- a/distro/pkg/rpm/knot-resolver.spec
+++ b/distro/pkg/rpm/knot-resolver.spec
@@ -299,6 +299,7 @@ getent passwd knot-resolver >/dev/null || useradd -r -g knot-resolver -d %{_sysc
%{_libdir}/knot-resolver/kres_modules/graphite.lua
%{_libdir}/knot-resolver/kres_modules/policy.lua
%{_libdir}/knot-resolver/kres_modules/predict.lua
+%{_libdir}/knot-resolver/kres_modules/prefetch.lua
%{_libdir}/knot-resolver/kres_modules/prefill.lua
%{_libdir}/knot-resolver/kres_modules/priming.lua
%{_libdir}/knot-resolver/kres_modules/rebinding.lua
diff --git a/modules/meson.build b/modules/meson.build
index 38612254..73444e99 100644
--- a/modules/meson.build
+++ b/modules/meson.build
@@ -7,6 +7,7 @@ lua_mod_src = [ # add lua modules without separate meson.build
files('dns64/dns64.lua'),
files('etcd/etcd.lua'),
files('graphite/graphite.lua'),
+ files('prefetch/prefetch.lua'),
files('predict/predict.lua'),
files('prefill/prefill.lua'),
files('priming/priming.lua'),
diff --git a/modules/prefetch/README.rst b/modules/prefetch/README.rst
new file mode 100644
index 00000000..4d5a5e3e
--- /dev/null
+++ b/modules/prefetch/README.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _mod-prefetch:
+
+Expiring records
+----------------
+
+The ``prefetch`` module helps to keep the cache hot by prefetching expiring records.
+
+This mechanism is activated when the module is loaded and it is not configurable.
+
+.. code-block:: lua
+
+ modules.load('prefetch')
+
+
+Any time the resolver answers with records that are about to expire, they get refreshed. (see :c:func:`is_expiring`)
+That improves latency for records which get frequently queried, relatively to their TTL.
diff --git a/modules/prefetch/prefetch.lua b/modules/prefetch/prefetch.lua
new file mode 100644
index 00000000..673cf3e5
--- /dev/null
+++ b/modules/prefetch/prefetch.lua
@@ -0,0 +1,21 @@
+-- SPDX-License-Identifier: GPL-3.0-or-later
+-- Speculative prefetching for repetitive and soon-expiring records to reduce latency.
+-- @module prefetch
+local prefetch = {}
+
+
+prefetch.layer = {
+ -- Prefetch all expiring (sub-)queries immediately after the request finishes.
+ -- Doing that immediately is simplest and avoids creating (new) large bursts of activity.
+ finish = function (_, req)
+ local qrys = req.rplan.resolved
+ for i = 0, (tonumber(qrys.len) - 1) do -- size_t doesn't work for some reason
+ local qry = qrys.at[i]
+ if qry.flags.EXPIRING == true then
+ resolve(kres.dname2str(qry.sname), qry.stype, qry.sclass, {'NO_CACHE'})
+ end
+ end
+ end
+}
+
+return prefetch