Skip to content

Commit 74bed9a

Browse files
authored
Merge pull request #518 from allegro/mg-ms-pluton-19231-optimize-render
PLUTON-19231 | Optimize vcl rendering fix #516
2 parents 2099ca4 + 9630c5a commit 74bed9a

File tree

8 files changed

+46
-142
lines changed

8 files changed

+46
-142
lines changed

envs/base.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
DEBUG=False
33
TEMPLATE_DEBUG=False
44
DJANGO_SETTINGS_MODULE=vaas.settings.docker
5-
PROMETHEUS_ENABLE=True
5+
PROMETHEUS_ENABLE=False
66
LOG_LEVEL=INFO

envs/dev.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
DEBUG=True
33
TEMPLATE_DEBUG=True
44
DJANGO_SETTINGS_MODULE=vaas.settings.docker
5-
PROMETHEUS_ENABLE=True
5+
PROMETHEUS_ENABLE=False
66
LOG_LEVEL=DEBUG

vaas/vaas/resources/dev-data.yaml

Lines changed: 1 addition & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -38,94 +38,6 @@
3838
remove_path: false
3939
time_profile: 1
4040
cluster: [1, 2, 3, 4]
41-
- model: cluster.dc
42-
pk: 1
43-
fields: {name: First datacenter, symbol: dc1}
44-
- model: cluster.dc
45-
pk: 2
46-
fields: {name: Second datacenter, symbol: dc2}
47-
- model: manager.backend
48-
pk: 1
49-
fields: {address: 192.168.199.10, port: 80, weight: 1, dc: 1, max_connections: 5,
50-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
51-
director: 1, enabled: true, inherit_time_profile: true}
52-
- model: manager.backend
53-
pk: 2
54-
fields: {address: 192.168.199.11, port: 80, weight: 1, dc: 1, max_connections: 5,
55-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
56-
director: 1, enabled: true, inherit_time_profile: true}
57-
- model: manager.backend
58-
pk: 3
59-
fields: {address: 192.168.199.12, port: 80, weight: 2, dc: 1, max_connections: 5,
60-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
61-
director: 1, enabled: true, inherit_time_profile: true}
62-
- model: manager.backend
63-
pk: 4
64-
fields: {address: 192.168.199.13, port: 80, weight: 3, dc: 1, max_connections: 5,
65-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
66-
director: 2, enabled: true, inherit_time_profile: true}
67-
- model: manager.backend
68-
pk: 5
69-
fields: {address: 192.168.199.14, port: 80, weight: 4, dc: 1, max_connections: 5,
70-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
71-
director: 2, enabled: true, inherit_time_profile: true}
72-
- model: manager.backend
73-
pk: 6
74-
fields: {address: 192.168.199.15, port: 80, weight: 5, dc: 1, max_connections: 5,
75-
connect_timeout: '0.30', first_byte_timeout: '5.00', between_bytes_timeout: '1.00',
76-
director: 2, enabled: true, inherit_time_profile: true}
77-
- model: cluster.logicalcluster
78-
pk: 1
79-
fields: {name: cluster1_siteA_test, reload_timestamp: '2019-11-19T08:02:15.994071+00:00',
80-
error_timestamp: '2019-11-13T07:46:40.450785+00:00', last_error_info: null,
81-
current_vcl_versions: '[]', labels_list: '["one:192.168.199.6"]'}
82-
- model: cluster.logicalcluster
83-
pk: 2
84-
fields: {name: cluster2_siteB_test, reload_timestamp: '2019-11-18T14:16:58.664933+00:00',
85-
error_timestamp: '2019-11-13T07:46:40.453146+00:00', last_error_info: null,
86-
current_vcl_versions: '[]', labels_list: '["two:192.168.199.4", "env:dev"]'}
87-
- model: cluster.logicalcluster
88-
pk: 3
89-
fields: {name: cluster3_siteA_dev, reload_timestamp: '2019-11-18T14:16:58.664933+00:00',
90-
error_timestamp: '2019-11-13T07:46:40.453839+00:00', last_error_info: null,
91-
current_vcl_versions: '[]', labels_list: '["example.com"]'}
92-
- model: cluster.logicalcluster
93-
pk: 4
94-
fields: {name: cluster4_siteC_prod, reload_timestamp: '2019-11-18T14:30:12.551574+00:00',
95-
error_timestamp: '2019-11-13T07:46:40.454405+00:00', last_error_info: null,
96-
current_vcl_versions: '[]', labels_list: '["placeholder:cluster4"]'}
97-
- model: cluster.domainmapping
98-
pk: 1
99-
fields: {domain: "mydomain.com", mappings_list: '["{one}:6081","{two}:6081"]', type: dynamic, clusters: []}
100-
- model: cluster.domainmapping
101-
pk: 2
102-
fields: {domain: "example.com", mappings_list: '["example.base.com"]', type: static, clusters: [3]}
103-
- model: cluster.vcltemplate
104-
pk: 2
105-
fields: {name: vagrant_template_4, content: "<VCL/>", version: '4.0', comment: wefwef}
106-
- model: cluster.varnishserver
107-
pk: 3
108-
fields: {ip: 192.168.199.4, hostname: varnish-4.1, cluster_weight: 1, http_port: 6081,
109-
port: 6082, secret: edcf6c52-6f93-4d0d-82b9-cd74239146b0, status: active, dc: 1,
110-
template: 2, cluster: 2, is_canary: false}
111-
- model: cluster.varnishserver
112-
pk: 4
113-
fields: {ip: 192.168.199.6, hostname: varnish-6, cluster_weight: 1, http_port: 6081,
114-
port: 6082, secret: edcf6c52-6f93-4d0d-82b9-cd74239146b0, status: active, dc: 1,
115-
template: 2, cluster: 1, is_canary: false}
116-
- model: cluster.varnishserver
117-
pk: 2
118-
fields: {ip: 192.168.199.7, hostname: varnish-7, cluster_weight: 1, http_port: 6081,
119-
port: 6082, secret: edcf6c52-6f93-4d0d-82b9-cd74239146b0, status: active, dc: 1,
120-
template: 2, cluster: 1, is_canary: false}
121-
- model: router.route
122-
pk: 1
123-
fields:
124-
condition: req.url ~ "^\/flexibleee"
125-
priority: 51
126-
director: 2
127-
action: pass
128-
clusters: [2]
12941
- model: router.positiveurl
13042
pk: 1
13143
fields: {url: http://192.168.199.4:6081/flexibleee, route: 1}
@@ -147,7 +59,7 @@
14759
- model: router.redirect
14860
pk: 1
14961
fields:
150-
src_domain: 1
62+
src_domain: 3
15163
condition: req.url ~ "/source_url"
15264
destination: http://mydomain.com/destination_url
15365
action: 301

vaas/vaas/router/models.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# -*- coding: utf-8 -*-
22
import uuid
3-
from typing import Dict, Tuple, List
3+
from typing import Dict
44
from django.db import models
55
from django.conf import settings
66
from django.core.validators import MinValueValidator, MaxValueValidator
7-
from urllib.parse import urlsplit
87

98
from vaas.cluster.models import DomainMapping, LogicalCluster
109
from vaas.manager.models import Director
@@ -37,16 +36,6 @@ class ResponseStatusCode(models.IntegerChoices):
3736
def get_hashed_assertions_pks(self) -> Dict[int, int]:
3837
return {hash((a.given_url, a.expected_location)): a.pk for a in self.assertions.all()}
3938

40-
def fetch_all_destinations_mappings(self, cluster: LogicalCluster) -> Tuple[str, List[str]]:
41-
"""
42-
Fetch tuple containing domain parsed from destination url and all found mappings for input cluster
43-
"""
44-
all_mappings = set()
45-
destination_domain = urlsplit(self.destination).netloc
46-
for domain_mapping in DomainMapping.objects.filter(domain=destination_domain):
47-
all_mappings = all_mappings.union(set(domain_mapping.mapped_domains(cluster)))
48-
return destination_domain, list(all_mappings)
49-
5039
@property
5140
def final_condition(self):
5241
if self.required_custom_header:

vaas/vaas/vcl/renderer.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import hashlib
66
import time
77
import functools
8-
from typing import Dict, List
8+
from urllib.parse import urlsplit
99

1010
from django.conf import settings
1111
from django.db.models import Prefetch
@@ -186,13 +186,26 @@ def __init__(self, varnish, input_data):
186186
'mesh_routing': varnish.cluster.service_mesh_routing
187187
}
188188

189+
def fetch_all_destinations_mappings(self, cluster: LogicalCluster, redirect: str,
190+
domain_mappings: list[DomainMapping]) -> tuple[str, list[str]]:
191+
"""Fetch tuple containing domain parsed from destination url and all found mappings for input cluster
192+
"""
193+
all_mappings = set()
194+
destination_domain = urlsplit(redirect).netloc
195+
for domain_mapping in domain_mappings:
196+
all_mappings = all_mappings.union(set(domain_mapping.mapped_domains(cluster)))
197+
return destination_domain, list(all_mappings)
198+
189199
@collect_processing
190-
def prepare_redirects(self) -> Dict[str, List[VclRedirect]]:
191-
redirects = {}
192-
related_domains = MappingProvider(DomainMapping.objects.all()).provide_related_domains(self.varnish.cluster)
193-
for redirect in self.input.redirects:
194-
destination_domain, destination_mappings = redirect.fetch_all_destinations_mappings(self.varnish.cluster)
195-
if str(redirect.src_domain) in related_domains:
200+
def prepare_redirects(self) -> dict[str, list[VclRedirect]]:
201+
redirects = dict()
202+
related_domains = self.input.mapping_provider.provide_related_domains(self.varnish.cluster)
203+
for related_domain in related_domains:
204+
if related_domain not in self.input.redirects.keys():
205+
continue
206+
for redirect in self.input.redirects.get(related_domain):
207+
destination_domain, destination_mappings = self.fetch_all_destinations_mappings(
208+
self.varnish.cluster, redirect.destination, self.input.domain_mappings)
196209
for mapped_domain in redirect.src_domain.mapped_domains(self.varnish.cluster):
197210
destination = str(redirect.destination)
198211
if destination_domain == redirect.src_domain.domain:
@@ -382,7 +395,7 @@ def fetch_render_data(self):
382395
Prefetch('clusters', queryset=LogicalCluster.objects.only('pk'), to_attr='cluster_ids'),
383396
))
384397
self.routes.sort(key=lambda route: "{:03d}-{}".format(route.priority, route.director.name))
385-
self.redirects = list(Redirect.objects.all().order_by('src_domain', 'priority'))
398+
self.redirects = self.assemble_redirects()
386399
self.dcs = list(Dc.objects.all())
387400
self.template_blocks = list(VclTemplateBlock.objects.all().prefetch_related('template'))
388401
self.vcl_variables = list(VclVariable.objects.all())
@@ -392,6 +405,17 @@ def fetch_render_data(self):
392405
)
393406
self.distributed_backends = self.distribute_backends(backends)
394407
self.distributed_canary_backends = self.prepare_canary_backends(canary_backend_ids, backends)
408+
self.domain_mappings = DomainMapping.objects.all()
409+
self.mapping_provider = MappingProvider(self.domain_mappings)
410+
411+
@collect_processing
412+
def assemble_redirects(self) -> dict[str, list[Redirect]]:
413+
redirects = {}
414+
for redirect in Redirect.objects.all().order_by('src_domain', 'priority'):
415+
if redirect.src_domain.domain not in redirects.keys():
416+
redirects[redirect.src_domain.domain] = []
417+
redirects[redirect.src_domain.domain].append(redirect)
418+
return redirects
395419

396420
@collect_processing
397421
def distribute_backends(self, backends):

vaas/vaas/vcl/tests/expected-vcl-4.0-canary.vcl

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ sub vcl_synth {
339339
if (resp.status == 989) {
340340
set resp.status = 200;
341341
set resp.http.Content-Type = "application/json";
342-
synthetic ( {"{ "vcl_version" : "0bbef", "varnish_status": "disabled" }"} );
342+
synthetic ( {"{ "vcl_version" : "ce716", "varnish_status": "disabled" }"} );
343343
return (deliver);
344344
}
345345
}
@@ -424,12 +424,6 @@ sub vcl_recv {
424424
set req.http.x-response-code = "301";
425425
set req.http.x-action = "redirect";
426426
}
427-
else if (req.url ~ "/external") {
428-
set req.http.x-redirect = "3";
429-
set req.http.x-destination = "http://example-external.com/external_destination";
430-
set req.http.x-response-code = "301";
431-
set req.http.x-action = "redirect";
432-
}
433427
}
434428
if (req.http.host == "example.prod.org") {
435429
if (req.url ~ "/source") {
@@ -444,12 +438,6 @@ sub vcl_recv {
444438
set req.http.x-response-code = "301";
445439
set req.http.x-action = "redirect";
446440
}
447-
else if (req.url ~ "/external") {
448-
set req.http.x-redirect = "3";
449-
set req.http.x-destination = "http://example-external.com/external_destination";
450-
set req.http.x-response-code = "301";
451-
set req.http.x-action = "redirect";
452-
}
453441
}
454442

455443
# Test ROUTER

vaas/vaas/vcl/tests/expected-vcl-4.0.vcl

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ sub vcl_synth {
366366
if (resp.status == 989) {
367367
set resp.status = 200;
368368
set resp.http.Content-Type = "application/json";
369-
synthetic ( {"{ "vcl_version" : "d584a", "varnish_status": "disabled" }"} );
369+
synthetic ( {"{ "vcl_version" : "721d3", "varnish_status": "disabled" }"} );
370370
return (deliver);
371371
}
372372
}
@@ -451,12 +451,6 @@ sub vcl_recv {
451451
set req.http.x-response-code = "301";
452452
set req.http.x-action = "redirect";
453453
}
454-
else if (req.url ~ "/external") {
455-
set req.http.x-redirect = "3";
456-
set req.http.x-destination = "http://example-external.com/external_destination";
457-
set req.http.x-response-code = "301";
458-
set req.http.x-action = "redirect";
459-
}
460454
}
461455
if (req.http.host == "example.prod.org") {
462456
if (req.url ~ "/source") {
@@ -471,12 +465,6 @@ sub vcl_recv {
471465
set req.http.x-response-code = "301";
472466
set req.http.x-action = "redirect";
473467
}
474-
else if (req.url ~ "/external") {
475-
set req.http.x-redirect = "3";
476-
set req.http.x-destination = "http://example-external.com/external_destination";
477-
set req.http.x-response-code = "301";
478-
set req.http.x-action = "redirect";
479-
}
480468
}
481469

482470
# Test ROUTER

vaas/vaas/vcl/tests/test_renderer.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def setUp(self):
280280
)
281281

282282
Redirect.objects.create(
283-
src_domain=self.example_domain_mapping,
283+
src_domain=self.external_domain_mapping,
284284
condition='req.url ~ "/external"',
285285
destination='http://external.com/external_destination',
286286
action=301,
@@ -436,23 +436,26 @@ def test_should_decorate_set_backend_tag_with_fallback_service_in_dc1(self):
436436
def test_should_decorate_flexible_router_tag_with_properly_mapped_destination_domain(self):
437437
vcl_tag_builder = VclTagBuilder(self.varnish, VclRendererInput())
438438
tag = vcl_tag_builder.get_expanded_tags('FLEXIBLE_ROUTER').pop()
439-
assert_set_equal({'example.prod.com', 'example.prod.org'}, set(tag.parameters['redirects'].keys()))
439+
assert_set_equal({'example.prod.com', 'example-external.com', 'example.prod.org'},
440+
set(tag.parameters['redirects'].keys()))
440441
assert_equals('example.com', tag.parameters['redirects']['example.prod.com'][1].src_domain.domain)
441442
assert_equals('example.com', tag.parameters['redirects']['example.prod.org'][1].src_domain.domain)
442443
assert_equals('http://example.prod.com/destination',
443444
tag.parameters['redirects']['example.prod.com'][1].destination)
444445
assert_equals('http://example.prod.org/destination',
445446
tag.parameters['redirects']['example.prod.org'][1].destination)
446447
assert_equals('http://example-external.com/external_destination',
447-
tag.parameters['redirects']['example.prod.com'][2].destination)
448+
tag.parameters['redirects']['example-external.com'][0].destination)
448449

449450
def test_should_sort_redirects_by_priority(self):
450451
vcl_tag_builder = VclTagBuilder(self.varnish, VclRendererInput())
451452
tag = vcl_tag_builder.get_expanded_tags('FLEXIBLE_ROUTER').pop()
452-
assert_set_equal({'example.prod.com', 'example.prod.org'}, set(tag.parameters['redirects'].keys()))
453+
assert_set_equal({'example.prod.com', 'example-external.com', 'example.prod.org'},
454+
set(tag.parameters['redirects'].keys()))
453455
assert_equals('2/example.prod.com', tag.parameters['redirects']['example.prod.com'][0].id)
454456
assert_equals('1/example.prod.com', tag.parameters['redirects']['example.prod.com'][1].id)
455-
assert_equals('3/example.prod.com', tag.parameters['redirects']['example.prod.com'][2].id)
457+
assert_equals('2/example.prod.org', tag.parameters['redirects']['example.prod.org'][0].id)
458+
assert_equals('3/example-external.com', tag.parameters['redirects']['example-external.com'][0].id)
456459

457460

458461
class VclRendererInputTest(TestCase):

0 commit comments

Comments
 (0)