Cache package provider and dependency information

Message ID 20191006172156.6842-1-lfleischer@archlinux.org
State New
Headers show
Series
  • Cache package provider and dependency information
Related show

Commit Message

Lukas Fleischer Oct. 6, 2019, 5:21 p.m. UTC
The package provider and dependency queries are quite CPU-intensive and
usually yield rather small result sets. Cache these values if the global
caching mechanism is enabled.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
---
We will test this in our production environment for a while to see
whether it makes any difference in server load. There are probably more
things that we easily cache and there's a lot of room for improvement in
general (e.g. increase the TTL and automatically invalidate the cache
when a new package version is pushed via Git).

 web/lib/cachefuncs.inc.php | 17 ++++++++++++++++
 web/lib/pkgfuncs.inc.php   | 40 +++++++++++---------------------------
 2 files changed, 28 insertions(+), 29 deletions(-)

Patch

diff --git a/web/lib/cachefuncs.inc.php b/web/lib/cachefuncs.inc.php
index 881ad8f..d0e0f6f 100644
--- a/web/lib/cachefuncs.inc.php
+++ b/web/lib/cachefuncs.inc.php
@@ -79,4 +79,21 @@  function db_cache_value($dbq, $key, $ttl=600) {
 	return $value;
 }
 
+# Run a simple db query, retrieving and/or caching the result set if APC is
+# available for use. Accepts an optional TTL value (defaults to 600 seconds).
+function db_cache_result($dbq, $key, $ttl=600) {
+	$dbh = DB::connect();
+	$status = false;
+	$value = get_cache_value($key, $status);
+	if (!$status) {
+		$result = $dbh->query($dbq);
+		if (!$result) {
+			return false;
+		}
+		$value = $result->fetchAll(PDO::FETCH_NUM);
+		set_cache_value($key, $value, $ttl);
+	}
+	return $value;
+}
+
 ?>
diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php
index 00f0cc4..44e4167 100644
--- a/web/lib/pkgfuncs.inc.php
+++ b/web/lib/pkgfuncs.inc.php
@@ -222,17 +222,7 @@  function pkg_providers($name) {
 	$q.= "UNION ";
 	$q.= "SELECT 0, Name FROM OfficialProviders ";
 	$q.= "WHERE Provides = " . $dbh->quote($name);
-	$result = $dbh->query($q);
-
-	if (!$result) {
-		return array();
-	}
-
-	$providers = array();
-	while ($row = $result->fetch(PDO::FETCH_NUM)) {
-		$providers[] = $row;
-	}
-	return $providers;
+	return db_cache_result($q, 'providers:' . $name);
 }
 
 /**
@@ -244,26 +234,18 @@  function pkg_providers($name) {
  * @return array All package dependencies for the package
  */
 function pkg_dependencies($pkgid, $limit) {
-	$deps = array();
 	$pkgid = intval($pkgid);
-	if ($pkgid > 0) {
-		$dbh = DB::connect();
-		$q = "SELECT pd.DepName, dt.Name, pd.DepDesc, ";
-		$q.= "pd.DepCondition, pd.DepArch, p.ID ";
-		$q.= "FROM PackageDepends pd ";
-		$q.= "LEFT JOIN Packages p ON pd.DepName = p.Name ";
-		$q.= "LEFT JOIN DependencyTypes dt ON dt.ID = pd.DepTypeID ";
-		$q.= "WHERE pd.PackageID = ". $pkgid . " ";
-		$q.= "ORDER BY pd.DepName LIMIT " . intval($limit);
-		$result = $dbh->query($q);
-		if (!$result) {
-			return array();
-		}
-		while ($row = $result->fetch(PDO::FETCH_NUM)) {
-			$deps[] = $row;
-		}
+	if (!$pkgid) {
+		return array();
 	}
-	return $deps;
+	$q = "SELECT pd.DepName, dt.Name, pd.DepDesc, ";
+	$q.= "pd.DepCondition, pd.DepArch, p.ID ";
+	$q.= "FROM PackageDepends pd ";
+	$q.= "LEFT JOIN Packages p ON pd.DepName = p.Name ";
+	$q.= "LEFT JOIN DependencyTypes dt ON dt.ID = pd.DepTypeID ";
+	$q.= "WHERE pd.PackageID = ". $pkgid . " ";
+	$q.= "ORDER BY pd.DepName LIMIT " . intval($limit);
+	return db_cache_result($q, 'dependencies:' . $name);
 }
 
 /**