Enable caching of blobs in V2 registry protocol, to avoid DB connections after the cache has been loaded

This should help for bursty pull traffic, as it will avoid DB connections on a huge % of requests
This commit is contained in:
Joseph Schorr 2017-12-14 13:38:24 -05:00
parent db6007cb37
commit b2485934ed
5 changed files with 112 additions and 13 deletions

View file

@ -1,4 +1,5 @@
import binascii
import copy
import hashlib
import json
import logging
@ -118,6 +119,19 @@ def addtoken():
return 'OK'
@testbp.route('/breakdatabase', methods=['POST'])
def break_database():
# Close any existing connection.
close_db_filter(None)
# Reload the database config with an invalid connection.
config = copy.copy(app.config)
config['DB_URI'] = 'sqlite:///not/a/valid/database'
configure(config)
return 'OK'
@testbp.route('/reloadapp', methods=['POST'])
def reload_app():
# Close any existing connection.
@ -1674,6 +1688,22 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix
def test_cancel_push(self):
self.do_push('devtable', 'newrepo', 'devtable', 'password', cancel=True)
def test_with_blob_caching(self):
# Add a repository and do a pull, to prime the cache.
_, manifests = self.do_push('devtable', 'newrepo', 'devtable', 'password')
self.do_pull('devtable', 'newrepo', 'devtable', 'password')
# Purposefully break the database so that we can check if caching works.
self.conduct('POST', '/__test/breakdatabase')
# Attempt to pull the blobs and ensure we get back a result. Since the database is broken,
# this will only work if caching is working and no additional queries/connections are made.
repo_name = 'devtable/newrepo'
for tag_name in manifests:
for layer in manifests[tag_name].layers:
blob_id = str(layer.digest)
self.conduct('GET', '/v2/%s/blobs/%s' % (repo_name, blob_id), expected_code=200, auth='jwt')
def test_pull_by_checksum(self):
# Add a new repository under the user, so we have a real repository to pull.
_, manifests = self.do_push('devtable', 'newrepo', 'devtable', 'password')