Skip to content

Commit 6640472

Browse files
committed
ensure atomic writes when saving a file
Right now, if a program crashes in the middle of saving, you lose all your data. Right now, if a program crashes in the middle of saving, you lose all your data. This ensures that the old file is first moved, then the new file is saved, and only then the old file is removed.
1 parent d79512f commit 6640472

File tree

4 files changed

+17
-4
lines changed

4 files changed

+17
-4
lines changed

adaptive/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from contextlib import contextmanager
88
from itertools import product
99

10+
from atomicwrites import AtomicWriter
11+
1012

1113
def named_product(**items):
1214
names = items.keys()
@@ -44,9 +46,13 @@ def save(fname, data, compress=True):
4446
dirname = os.path.dirname(fname)
4547
if dirname:
4648
os.makedirs(dirname, exist_ok=True)
47-
_open = gzip.open if compress else open
48-
with _open(fname, "wb") as f:
49-
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
49+
50+
blob = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
51+
if compress:
52+
blob = gzip.compress(blob)
53+
54+
with AtomicWriter(fname, "wb", overwrite=True).open() as f:
55+
f.write(blob)
5056

5157

5258
def load(fname, compress=True):

docs/environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies:
1212
- bokeh=1.0.4
1313
- plotly=3.9.0
1414
- ipywidgets=7.4.2
15+
- atomicwrites=1.3.0
1516
- pip:
1617
- git+https://github.com/basnijholt/jupyter-sphinx.git@widgets_execute
1718
- sphinx_fontawesome==0.0.6

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ dependencies:
1616
- ipywidgets
1717
- scikit-optimize
1818
- plotly
19+
- atomicwrites

setup.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ def get_version_and_cmdclass(package_name):
2424
version, cmdclass = get_version_and_cmdclass("adaptive")
2525

2626

27-
install_requires = ["scipy", "sortedcollections >= 1.1", "sortedcontainers >= 2.0"]
27+
install_requires = [
28+
"scipy",
29+
"sortedcollections >= 1.1",
30+
"sortedcontainers >= 2.0",
31+
"atomicwrites",
32+
]
2833

2934
extras_require = {
3035
"notebook": [

0 commit comments

Comments
 (0)