Skip to content

Commit 08cda5e

Browse files
committed
Enable caching by default for API requests and Library Manager
1 parent 6de8325 commit 08cda5e

File tree

8 files changed

+87
-29
lines changed

8 files changed

+87
-29
lines changed

HISTORY.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ PlatformIO 3.0
4444
* Added global ``lib_extra_dirs`` option to ``[platformio]`` section for
4545
`Project Configuration File "platformio.ini" <http://docs.platformio.org/en/stable/projectconf.html>`__
4646
(`issue #842 <https://github.com/platformio/platformio-core/issues/842>`_)
47+
* Enabled caching by default for API requests and Library Manager (see `enable_cache <http://docs.platformio.org/en/latest/userguide/cmd_settings.html#enable-cache>`__ setting)
4748
* Changed a default exit combination for Device Monitor from ``Ctrl+]`` to ``Ctrl+C``
4849
* Improved detecting of ARM mbed media disk for uploading
4950
* Improved Project Generator for CLion IDE when source folder contains nested items

docs/userguide/cmd_settings.rst

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,16 @@ Check for the platform updates interval.
9797

9898
Enable SSL for PlatformIO Services
9999

100+
.. _enable_cache:
101+
102+
``enable_cache``
103+
^^^^^^^^^^^^^^^^
104+
105+
:Default: Yes
106+
:Values: Yes/No
107+
108+
Enable caching for API requests and Library Manager
109+
100110
.. _setting_force_verbose:
101111

102112
``force_verbose``
@@ -144,17 +154,21 @@ Examples
144154

145155
1. List all settings and theirs current values
146156

147-
.. code-block:: bash
157+
.. code::
158+
159+
> platformio settings get
148160
149-
$ platformio settings get
150161
Name Value [Default] Description
151162
------------------------------------------------------------------------------------------
152-
auto_update_libraries Yes Automatically update libraries (Yes/No)
153-
auto_update_platforms Yes Automatically update platforms (Yes/No)
163+
auto_update_libraries No Automatically update libraries (Yes/No)
164+
auto_update_platforms No Automatically update platforms (Yes/No)
154165
check_libraries_interval 7 Check for the library updates interval (days)
155166
check_platformio_interval 3 Check for the new PlatformIO interval (days)
156167
check_platforms_interval 7 Check for the platform updates interval (days)
168+
enable_cache Yes Enable caching for API requests and Library Manager
169+
enable_ssl No Enable SSL for PlatformIO Services
157170
enable_telemetry Yes Telemetry service (Yes/No)
171+
force_verbose No Force verbose output when processing environments
158172
159173
160174
2. Show specified setting
@@ -223,8 +237,12 @@ Examples
223237
224238
Name Value [Default] Description
225239
------------------------------------------------------------------------------------------
226-
auto_update_libraries Yes Automatically update libraries (Yes/No)
227-
auto_update_platforms Yes Automatically update platforms (Yes/No)
240+
auto_update_libraries No Automatically update libraries (Yes/No)
241+
auto_update_platforms No Automatically update platforms (Yes/No)
228242
check_libraries_interval 7 Check for the library updates interval (days)
229243
check_platformio_interval 3 Check for the new PlatformIO interval (days)
230244
check_platforms_interval 7 Check for the platform updates interval (days)
245+
enable_cache Yes Enable caching for API requests and Library Manager
246+
enable_ssl No Enable SSL for PlatformIO Services
247+
enable_telemetry Yes Telemetry service (Yes/No)
248+
force_verbose No Force verbose output when processing environments

platformio/app.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
"description": "Enable SSL for PlatformIO Services",
5757
"value": False
5858
},
59+
"enable_cache": {
60+
"description": "Enable caching for API requests and Library Manager",
61+
"value": True
62+
},
5963
"enable_telemetry": {
6064
"description":
6165
("Telemetry service <http://docs.platformio.org/en/stable/"
@@ -122,16 +126,20 @@ def _unlock_state_file(self):
122126
self._lockfile.release()
123127

124128

125-
class LocalCache(object):
129+
class ContentCache(object):
126130

127131
def __init__(self, cache_dir=None):
132+
self.cache_dir = None
133+
self.db_path = None
134+
if not get_setting("enable_cache"):
135+
return
128136
self.cache_dir = cache_dir or join(util.get_home_dir(), ".cache")
129137
if not self.cache_dir:
130138
os.makedirs(self.cache_dir)
131139
self.db_path = join(self.cache_dir, "db.data")
132140

133141
def __enter__(self):
134-
if not isfile(self.db_path):
142+
if not self.db_path or not isfile(self.db_path):
135143
return self
136144
newlines = []
137145
found = False
@@ -169,24 +177,26 @@ def key_from_args(*args):
169177
return h.hexdigest()
170178

171179
def get(self, key):
180+
if not self.cache_dir:
181+
return None
172182
cache_path = self.get_cache_path(key)
173183
if not isfile(cache_path):
174184
return None
175-
with open(cache_path) as fp:
185+
with open(cache_path, "rb") as fp:
176186
data = fp.read()
177187
if data[0] in ("{", "["):
178188
return json.loads(data)
179189
return data
180190

181191
def set(self, key, data, valid):
182-
if not data:
192+
if not self.cache_dir or not data:
183193
return
184194
tdmap = {"s": 1, "m": 60, "h": 3600, "d": 86400}
185195
assert valid.endswith(tuple(tdmap.keys()))
186196
cache_path = self.get_cache_path(key)
187197
if not isdir(dirname(cache_path)):
188198
os.makedirs(dirname(cache_path))
189-
with open(cache_path, "w") as fp:
199+
with open(cache_path, "wb") as fp:
190200
if isinstance(data, dict) or isinstance(data, list):
191201
json.dump(data, fp)
192202
else:
@@ -197,7 +207,7 @@ def set(self, key, data, valid):
197207
return True
198208

199209
def clean(self):
200-
if isdir(self.cache_dir):
210+
if self.cache_dir and isdir(self.cache_dir):
201211
util.rmtree_(self.cache_dir)
202212

203213

platformio/maintenance.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ def in_silence(ctx=None):
4343

4444

4545
def clean_cache():
46-
with app.LocalCache() as lc:
47-
lc.clean()
46+
with app.ContentCache() as cc:
47+
cc.clean()
4848

4949

5050
def on_platformio_start(ctx, force, caller):

platformio/managers/lib.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,11 @@ def _cmp_dates(datestr1, datestr2):
170170

171171
def get_latest_repo_version(self, name, requirements):
172172
item = self.max_satisfying_repo_version(
173-
util.get_api_result("/lib/versions/%d" % self._get_pkg_id_by_name(
174-
name, requirements)), requirements)
173+
util.get_api_result(
174+
"/lib/versions/%d" % self._get_pkg_id_by_name(name,
175+
requirements),
176+
cache_valid="1h"),
177+
requirements)
175178
return item['version'] if item else None
176179

177180
def _get_pkg_id_by_name(self,

platformio/managers/package.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414

1515
import json
1616
import os
17-
from os.path import basename, dirname, isdir, isfile, islink, join
18-
from shutil import copytree
17+
import shutil
18+
from os.path import basename, dirname, getsize, isdir, isfile, islink, join
1919
from tempfile import mkdtemp
2020

2121
import click
2222
import requests
2323
import semantic_version
2424

25-
from platformio import exception, telemetry, util
25+
from platformio import app, exception, telemetry, util
2626
from platformio.downloader import FileDownloader
2727
from platformio.unpacker import FileUnpacker
2828
from platformio.vcsclient import VCSClientFactory
@@ -190,7 +190,7 @@ def _install_from_url(self, name, url, requirements=None, sha1=None):
190190
self.unpack(url, tmp_dir)
191191
else:
192192
util.rmtree_(tmp_dir)
193-
copytree(url, tmp_dir)
193+
shutil.copytree(url, tmp_dir)
194194
elif url.startswith(("http://", "https://")):
195195
dlpath = self.download(url, tmp_dir, sha1)
196196
assert isfile(dlpath)
@@ -262,6 +262,9 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
262262

263263
_INSTALLED_CACHE = {}
264264

265+
FILE_CACHE_VALID = "1m" # 1 month
266+
FILE_CACHE_MAX_SIZE = 1024 * 1024
267+
265268
def __init__(self, package_dir, repositories=None):
266269
self.repositories = repositories
267270
self.package_dir = package_dir
@@ -273,13 +276,32 @@ def __init__(self, package_dir, repositories=None):
273276
def manifest_name(self):
274277
raise NotImplementedError()
275278

276-
@staticmethod
277-
def download(url, dest_dir, sha1=None):
279+
def download(self, url, dest_dir, sha1=None):
280+
cache_key_fname = app.ContentCache.key_from_args(url, "fname")
281+
cache_key_data = app.ContentCache.key_from_args(url, "data")
282+
if self.FILE_CACHE_VALID:
283+
with app.ContentCache() as cc:
284+
fname = cc.get(cache_key_fname)
285+
cache_path = cc.get_cache_path(cache_key_data)
286+
if fname and isfile(cache_path):
287+
dst_path = join(dest_dir, fname)
288+
shutil.copy(cache_path, dst_path)
289+
return dst_path
290+
278291
fd = FileDownloader(url, dest_dir)
279292
fd.start()
280293
if sha1:
281294
fd.verify(sha1)
282-
return fd.get_filepath()
295+
dst_path = fd.get_filepath()
296+
if not self.FILE_CACHE_VALID or getsize(
297+
dst_path) > BasePkgManager.FILE_CACHE_MAX_SIZE:
298+
return dst_path
299+
300+
with app.ContentCache() as cc:
301+
cc.set(cache_key_fname, basename(dst_path), self.FILE_CACHE_VALID)
302+
cc.set(cache_key_data, "DUMMY", self.FILE_CACHE_VALID)
303+
shutil.copy(dst_path, cc.get_cache_path(cache_key_data))
304+
return dst_path
283305

284306
@staticmethod
285307
def unpack(source_path, dest_dir):
@@ -580,6 +602,8 @@ def update( # pylint: disable=too-many-return-statements
580602

581603
class PackageManager(BasePkgManager):
582604

605+
FILE_CACHE_VALID = None # disable package caching
606+
583607
@property
584608
def manifest_name(self):
585609
return "package.json"

platformio/managers/platform.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
class PlatformManager(BasePkgManager):
2929

30+
FILE_CACHE_VALID = None # disable platform caching
31+
3032
def __init__(self, package_dir=None, repositories=None):
3133
if not repositories:
3234
repositories = [

platformio/util.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,22 +482,22 @@ def _get_api_result(
482482

483483

484484
def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
485-
from platformio.app import LocalCache
485+
from platformio.app import ContentCache
486486
total = 0
487487
max_retries = 5
488-
cache_key = (LocalCache.key_from_args(url, params, data, auth)
488+
cache_key = (ContentCache.key_from_args(url, params, data, auth)
489489
if cache_valid else None)
490490
while total < max_retries:
491491
try:
492-
with LocalCache() as lc:
492+
with ContentCache() as cc:
493493
if cache_key:
494-
result = lc.get(cache_key)
494+
result = cc.get(cache_key)
495495
if result is not None:
496496
return result
497497
result = _get_api_result(url, params, data)
498498
if cache_valid:
499-
with LocalCache() as lc:
500-
lc.set(cache_key, result, cache_valid)
499+
with ContentCache() as cc:
500+
cc.set(cache_key, result, cache_valid)
501501
return result
502502
except (requests.exceptions.ConnectionError,
503503
requests.exceptions.Timeout) as e:

0 commit comments

Comments
 (0)