Refactor @memoized decorator with expiration feature; cache installed boards per platform

This commit is contained in:
Ivan Kravets
2018-03-23 00:08:07 +02:00
parent 0f4ab5b50b
commit d54327f1a9
7 changed files with 25 additions and 45 deletions

View File

@ -199,7 +199,7 @@ def _delete_file(path):
pass pass
@util.memoized @util.memoized()
def _get_compiler_type(env): def _get_compiler_type(env):
try: try:
sysenv = environ.copy() sysenv = environ.copy()

View File

@ -23,7 +23,7 @@ from platformio import exception, util
from platformio.managers.platform import PlatformFactory from platformio.managers.platform import PlatformFactory
@util.memoized @util.memoized()
def initPioPlatform(name): def initPioPlatform(name):
return PlatformFactory.newPlatform(name) return PlatformFactory.newPlatform(name)

View File

@ -40,7 +40,7 @@ class ProjectGenerator(object):
return sorted( return sorted(
[d for d in os.listdir(tpls_dir) if isdir(join(tpls_dir, d))]) [d for d in os.listdir(tpls_dir) if isdir(join(tpls_dir, d))])
@util.memoized @util.memoized()
def get_project_env(self): def get_project_env(self):
data = {} data = {}
config = util.load_project_config(self.project_dir) config = util.load_project_config(self.project_dir)
@ -54,7 +54,6 @@ class ProjectGenerator(object):
data[k] = v data[k] = v
return data return data
@util.memoized
def get_project_build_data(self): def get_project_build_data(self):
data = { data = {
"defines": [], "defines": [],

View File

@ -23,7 +23,7 @@ from platformio.managers.package import PackageManager
CORE_PACKAGES = { CORE_PACKAGES = {
"contrib-piohome": ">=0.9.1,<2", "contrib-piohome": ">=0.9.1,<2",
"contrib-pysite": ">=0.2.0,<2", "contrib-pysite": ">=0.2.0,<2",
"tool-pioplus": ">=1.1.2,<2", "tool-pioplus": ">=1.1.3,<2",
"tool-unity": "~1.20403.0", "tool-unity": "~1.20403.0",
"tool-scons": "~2.20501.4" "tool-scons": "~2.20501.4"
} }

View File

@ -398,7 +398,7 @@ class LibraryManager(BasePkgManager):
return pkg_dir return pkg_dir
@util.memoized @util.memoized()
def get_builtin_libs(storage_names=None): def get_builtin_libs(storage_names=None):
items = [] items = []
storage_names = storage_names or [] storage_names = storage_names or []
@ -417,7 +417,7 @@ def get_builtin_libs(storage_names=None):
return items return items
@util.memoized @util.memoized()
def is_builtin_lib(name): def is_builtin_lib(name):
for storage in get_builtin_libs(): for storage in get_builtin_libs():
if any(l.get("name") == name for l in storage['items']): if any(l.get("name") == name for l in storage['items']):

View File

@ -30,7 +30,7 @@ from platformio.managers.package import BasePkgManager, PackageManager
class PlatformManager(BasePkgManager): class PlatformManager(BasePkgManager):
FILE_CACHE_VALID = None # disable platform caching FILE_CACHE_VALID = None # disable platform download caching
def __init__(self, package_dir=None, repositories=None): def __init__(self, package_dir=None, repositories=None):
if not repositories: if not repositories:
@ -158,6 +158,7 @@ class PlatformManager(BasePkgManager):
self.cache_reset() self.cache_reset()
return True return True
@util.memoized(expire=5000)
def get_installed_boards(self): def get_installed_boards(self):
boards = [] boards = []
for manifest in self.get_installed(): for manifest in self.get_installed():
@ -169,7 +170,7 @@ class PlatformManager(BasePkgManager):
return boards return boards
@staticmethod @staticmethod
@util.memoized @util.memoized()
def get_registered_boards(): def get_registered_boards():
return util.get_api_result("/boards", cache_valid="7d") return util.get_api_result("/boards", cache_valid="7d")

View File

@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import collections
import functools
import json import json
import os import os
import platform import platform
@ -113,40 +111,22 @@ class cd(object):
class memoized(object): class memoized(object):
'''
Decorator. Caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned
(not reevaluated).
https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
'''
def __init__(self, func): def __init__(self, expire=0):
self.func = func self.expire = expire / 1000 # milliseconds
self.cache = {} self.cache = {}
def __call__(self, *args): def __call__(self, func):
if not isinstance(args, collections.Hashable):
# uncacheable. a list, for instance.
# better to not cache than blow up.
return self.func(*args)
if args in self.cache:
return self.cache[args]
value = self.func(*args)
self.cache[args] = value
return value
def __repr__(self): @wraps(func)
'''Return the function's docstring.''' def wrapper(*args, **kwargs):
return self.func.__doc__ key = str(args) + str(kwargs)
if (key not in self.cache
or self.cache[key][0] < time.time() - self.expire):
self.cache[key] = (time.time(), func(*args, **kwargs))
return self.cache[key][1]
def __get__(self, obj, objtype): return wrapper
'''Support instance methods.'''
fn = functools.partial(self.__call__, obj)
fn.reset = self._reset
return fn
def _reset(self):
self.cache = {}
class throttle(object): class throttle(object):
@ -155,15 +135,15 @@ class throttle(object):
self.threshhold = threshhold # milliseconds self.threshhold = threshhold # milliseconds
self.last = 0 self.last = 0
def __call__(self, fn): def __call__(self, func):
@wraps(fn) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
diff = int(round((time.time() - self.last) * 1000)) diff = int(round((time.time() - self.last) * 1000))
if diff < self.threshhold: if diff < self.threshhold:
time.sleep((self.threshhold - diff) * 0.001) time.sleep((self.threshhold - diff) * 0.001)
self.last = time.time() self.last = time.time()
return fn(*args, **kwargs) return func(*args, **kwargs)
return wrapper return wrapper
@ -568,7 +548,7 @@ def get_request_defheaders():
return {"User-Agent": "PlatformIO/%s CI/%d %s" % data} return {"User-Agent": "PlatformIO/%s CI/%d %s" % data}
@memoized @memoized(expire=10000)
def _api_request_session(): def _api_request_session():
return requests.Session() return requests.Session()
@ -671,7 +651,7 @@ PING_INTERNET_IPS = [
] ]
@memoized @memoized(expire=5000)
def _internet_on(): def _internet_on():
timeout = 2 timeout = 2
socket.setdefaulttimeout(timeout) socket.setdefaulttimeout(timeout)