What happens
get_database_matching_server_keys finds the database for a request by computing the expected HMAC authorization header for each candidate database until one matches. It is called once by each of eight validator modules and again by the endpoint handler:
src/mock_vws/_services_validators/auth_validators.py
src/mock_vws/_services_validators/database_id_validators.py
src/mock_vws/_services_validators/name_validators.py
src/mock_vws/_services_validators/project_state_validators.py
src/mock_vws/_services_validators/request_quota_validators.py
src/mock_vws/_services_validators/request_rate_validators.py
src/mock_vws/_services_validators/target_quota_validators.py
src/mock_vws/_services_validators/target_validators.py
Each of those calls re-walks the full database list from the start. Counting calls to vws_auth_tools.authorization_header for a single request:
databases=1: POST /targets -> 7 HMAC computations; GET /summary -> 5
databases=5: POST /targets -> 28 HMAC computations; GET /summary -> 20
So the cost is validators multiplied by databases, and the request's own signature is recomputed from its body every time. For POST /targets the body includes the base64-encoded image, so each of those 28 computations hashes the whole image again.
Why it matters
This is the mock's per-request baseline cost, paid on every endpoint, and it grows with the number of databases a test registers. It is not currently a reported problem, so this is about avoidable work rather than an observed regression.
The structural point is the more interesting one: the database is resolved nine separate times and each caller independently handles the "no database matches" case by catching ValueError. There is one answer per request and it is recomputed nine times.
Suggested resolution
Resolve the database once per request and pass the result to the validators and the handler.
This overlaps with #3371 but is separable, and is the smaller of the two: it does not require restructuring the validator chain, only threading an already-computed value through the signatures which currently take databases and re-derive it.
Note that the resolution has to stay lazy enough to preserve error precedence. validate_access_key_exists and validate_authorization deliberately run before the others and return different result codes for an unknown access key versus a bad signature, so "resolve first, then validate" cannot simply replace them.
What happens
get_database_matching_server_keysfinds the database for a request by computing the expected HMAC authorization header for each candidate database until one matches. It is called once by each of eight validator modules and again by the endpoint handler:Each of those calls re-walks the full database list from the start. Counting calls to
vws_auth_tools.authorization_headerfor a single request:So the cost is validators multiplied by databases, and the request's own signature is recomputed from its body every time. For
POST /targetsthe body includes the base64-encoded image, so each of those 28 computations hashes the whole image again.Why it matters
This is the mock's per-request baseline cost, paid on every endpoint, and it grows with the number of databases a test registers. It is not currently a reported problem, so this is about avoidable work rather than an observed regression.
The structural point is the more interesting one: the database is resolved nine separate times and each caller independently handles the "no database matches" case by catching
ValueError. There is one answer per request and it is recomputed nine times.Suggested resolution
Resolve the database once per request and pass the result to the validators and the handler.
This overlaps with #3371 but is separable, and is the smaller of the two: it does not require restructuring the validator chain, only threading an already-computed value through the signatures which currently take
databasesand re-derive it.Note that the resolution has to stay lazy enough to preserve error precedence.
validate_access_key_existsandvalidate_authorizationdeliberately run before the others and return different result codes for an unknown access key versus a bad signature, so "resolve first, then validate" cannot simply replace them.