Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sonic-cfggen] optimize sonic-cfggen startup #3658

Merged
merged 4 commits into from
Oct 31, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/sonic-config-engine/lazy_re.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# monkey patch re.compile to improve import time of some packages

import re

_orig_re_compile = re.compile

def __re_compile(*args, **kwargs):
class __LazyReCompile(object):
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.pattern_obj = None

def __getattr__(self, name):
if self.pattern_obj is None:
self.pattern_obj = _orig_re_compile(*self.args, **self.kwargs)
return getattr(self.pattern_obj, name)
return __LazyReCompile(*args, **kwargs)

re.compile = __re_compile


Copy link
Collaborator

@qiluo-msft qiluo-msft Oct 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several code format issues. Please check http://pep8online.com #Closed

26 changes: 26 additions & 0 deletions src/sonic-config-engine/redis_bcc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import jinja2

class RedisBytecodeCache(jinja2.BytecodeCache):
""" A bytecode cache for jinja2 template that stores bytecode in Redis """

REDIS_HASH = 'JINJA2_CACHE'

def __init__(self, client):
self._client = client
try:
self._client.connect(self._client.STATE_DB, retry_on=False)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STATE_DB [](start = 46, length = 8)

use another non-used database?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I use db index 8 and update swss-common/swss-sdk?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still applicable.


In reply to: 338815799 [](ancestors = 338815799)

except Exception:
self._client = None

def load_bytecode(self, bucket):
if self._client is None:
return
code = self._client.get(self._client.STATE_DB, self.REDIS_HASH, bucket.key)
if code is not None:
bucket.bytecode_from_string(code)

def dump_bytecode(self, bucket):
if self._client is None:
return
self._client.set(self._client.STATE_DB, self.REDIS_HASH, bucket.key, bucket.bytecode_to_string())

2 changes: 1 addition & 1 deletion src/sonic-config-engine/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def get_test_suite():
author='Taoyu Li',
author_email='taoyl@microsoft.com',
url='https://github.com/Azure/sonic-buildimage',
py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples'],
py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_device_util', 'config_samples', 'redis_bcc', 'lazy_re'],
scripts=['sonic-cfggen'],
install_requires=['lxml', 'jinja2>=2.10', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind==0.6.0'],
test_suite='setup.get_test_suite',
Expand Down
16 changes: 14 additions & 2 deletions src/sonic-config-engine/sonic-cfggen
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ See usage string for detail description for arguments.
"""

from __future__ import print_function

# mokey patch re.compile to do lazy regular expression compilation.
Copy link
Collaborator

@qiluo-msft qiluo-msft Oct 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mokey [](start = 2, length = 5)

typo #Closed

# This is done to improve import time of jinja2, yaml, natsort modules, because they
# do many regexp compilation at import time, so it will speed up sonic-cfggen invocations
# that do not require template generation or yaml loading. sonic-cfggen is used in so many places
# during system boot up that importing jinja2, yaml, natsort every time
# without lazy regular expression compilation affect boot up time.
# FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach
import lazy_re

import sys
import os.path
import argparse
Expand All @@ -33,7 +43,8 @@ from sonic_device_util import get_platform_info
from sonic_device_util import get_system_mac
from config_samples import generate_sample_config
from config_samples import get_available_config
from swsssdk import ConfigDBConnector
from swsssdk import SonicV2Connector, ConfigDBConnector
from redis_bcc import RedisBytecodeCache
from collections import OrderedDict
from natsort import natsorted

Expand Down Expand Up @@ -259,7 +270,8 @@ def main():
paths = ['/', '/usr/share/sonic/templates', os.path.dirname(template_file)]
loader = jinja2.FileSystemLoader(paths)

env = jinja2.Environment(loader=loader, trim_blocks=True)
redis_bcc = RedisBytecodeCache(SonicV2Connector(host='127.0.0.1'))
env = jinja2.Environment(loader=loader, trim_blocks=True, bytecode_cache=redis_bcc)
env.filters['sort_by_port_index'] = sort_by_port_index
env.filters['ipv4'] = is_ipv4
env.filters['ipv6'] = is_ipv6
Expand Down