From 88aea80913b1e732d321b7b13f2771e6c03cbb70 Mon Sep 17 00:00:00 2001 From: Erik Reid <erik.reid@geant.org> Date: Fri, 1 Mar 2019 15:19:46 +0100 Subject: [PATCH] cache peer-info responses --- inventory_provider/routes/classifier.py | 82 ++++++++++++++----------- inventory_provider/tasks/worker.py | 1 + 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py index dde5fa03..a39f7a0d 100644 --- a/inventory_provider/routes/classifier.py +++ b/inventory_provider/routes/classifier.py @@ -1,7 +1,7 @@ import ipaddress import json -from flask import Blueprint, Response, jsonify +from flask import Blueprint, Response from inventory_provider.routes import common @@ -92,40 +92,50 @@ def find_interfaces(address): @common.require_accepts_json def peer_info(address): - try: - address_obj = ipaddress.ip_address(address) - except ValueError: - return Response( - response='unable to parse %r as an ip address' % address, - status=422, - mimetype="text/html") - r = common.get_redis() - result = {} - - info = r.get('ix_public_peer:%s' % address) - if info: - info = info.decode('utf-8') - result['ix-public-peer-info'] = json.loads(info) - description = result['ix-public-peer-info']['description'] - assert description is not None # sanity - result['ix-public-peer-group'] = list( - ix_peering_group(address_obj, description)) - - info = r.get('vpn_rr_peer:%s' % address) - if info: - info = info.decode('utf-8') - result['vpn-rr-peer-info'] = json.loads(info) - - interfaces = list(find_interfaces(address_obj)) - if interfaces: - result['interfaces'] = interfaces - - if not result: - return Response( - response='no peering info found for %s' % address, - status=404, - mimetype="text/html") - - return jsonify(result) + cache_key = 'classifier:peer-cache:%s' % address + + result = r.get(cache_key) + if result: + result = result.decode('utf-8') + else: + try: + address_obj = ipaddress.ip_address(address) + except ValueError: + return Response( + response='unable to parse %r as an ip address' % address, + status=422, + mimetype="text/html") + + result = {} + + info = r.get('ix_public_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['ix-public-peer-info'] = json.loads(info) + description = result['ix-public-peer-info']['description'] + assert description is not None # sanity + result['ix-public-peer-group'] = list( + ix_peering_group(address_obj, description)) + + info = r.get('vpn_rr_peer:%s' % address) + if info: + info = info.decode('utf-8') + result['vpn-rr-peer-info'] = json.loads(info) + + interfaces = list(find_interfaces(address_obj)) + if interfaces: + result['interfaces'] = interfaces + + if not result: + return Response( + response='no peering info found for %s' % address, + status=404, + mimetype="text/html") + + result = json.dumps(result) + # cache this data for the next call + r.set(cache_key, result.encode('utf-8')) + + return Response(result, mimetype="application/json") diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py index 1830053b..59eb170d 100644 --- a/inventory_provider/tasks/worker.py +++ b/inventory_provider/tasks/worker.py @@ -260,6 +260,7 @@ def clear_cached_classifier_responses(hostname): r = get_redis(InventoryTask.config) for k in r.keys('classifier:cache:%s:*' % hostname): r.delete(k) + # TODO: remove peer-cache (after adding hostname to query) def _refresh_peers(hostname, key_base, peers): -- GitLab