From: Konrad Wojas Date: Thu, 26 Jan 2017 06:38:53 +0000 (+0800) Subject: Fix API performance: one DNSSECKeeper per request X-Git-Tag: rec-4.1.0-alpha1~284^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce846be61e4487f77e87463bf162c1bebb7c32eb;p=thirdparty%2Fpdns.git Fix API performance: one DNSSECKeeper per request getZoneInfo() was instantiating a new DNSSECKeeper for every call. Since DNSSECKeeper opens a new database connection, this resulted in severe performance issues in /api/v1/servers/localhost/zones with many zones. This is fixed by passing a DNSSECKeeper instance to getZoneInfo(). With 10,000 zones and the sqlite3 backend, this reduces the API call execution time from ~2s to ~200ms (from ~7s to 700ms for first call). --- diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index a3d75464e7..ac4b0e868f 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -302,8 +302,7 @@ static inline string makeBackendRecordContent(const QType& qtype, const string& return makeRecordContent(qtype, content, true); } -static Json::object getZoneInfo(const DomainInfo& di) { - DNSSECKeeper dk; +static Json::object getZoneInfo(const DomainInfo& di, DNSSECKeeper *dk) { string zoneId = apiZoneNameToId(di.zone); return Json::object { // id is the canonical lookup key, which doesn't actually match the name (in some cases) @@ -311,7 +310,7 @@ static Json::object getZoneInfo(const DomainInfo& di) { { "url", "/api/v1/servers/localhost/zones/" + zoneId }, { "name", di.zone.toString() }, { "kind", di.getKindString() }, - { "dnssec", dk.isSecuredZone(di.zone) }, + { "dnssec", dk->isSecuredZone(di.zone) }, { "account", di.account }, { "masters", di.masters }, { "serial", (double)di.serial }, @@ -326,7 +325,8 @@ static void fillZone(const DNSName& zonename, HttpResponse* resp) { if(!B.getDomainInfo(zonename, di)) throw ApiException("Could not find domain '"+zonename.toString()+"'"); - Json::object doc = getZoneInfo(di); + DNSSECKeeper dk; + Json::object doc = getZoneInfo(di, &dk); // extra stuff getZoneInfo doesn't do for us (more expensive) string soa_edit_api; di.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soa_edit_api); @@ -1153,7 +1153,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { Json::array doc; for(const DomainInfo& di : domains) { - doc.push_back(getZoneInfo(di)); + doc.push_back(getZoneInfo(di, &dk)); } resp->setBody(doc); }