|
@@ -1,5 +1,5 @@
|
|
|
from contextlib import contextmanager
|
|
|
-from datetime import datetime, timezone
|
|
|
+from datetime import datetime, timezone, timedelta
|
|
|
from getpass import getuser
|
|
|
from itertools import groupby
|
|
|
import errno
|
|
@@ -186,7 +186,7 @@ class Archive:
|
|
|
|
|
|
def __init__(self, repository, key, manifest, name, cache=None, create=False,
|
|
|
checkpoint_interval=300, numeric_owner=False, noatime=False, noctime=False, progress=False,
|
|
|
- chunker_params=CHUNKER_PARAMS, start=None, end=None):
|
|
|
+ chunker_params=CHUNKER_PARAMS, start=None, start_monotonic=None, end=None):
|
|
|
self.cwd = os.getcwd()
|
|
|
self.key = key
|
|
|
self.repository = repository
|
|
@@ -200,9 +200,12 @@ class Archive:
|
|
|
self.numeric_owner = numeric_owner
|
|
|
self.noatime = noatime
|
|
|
self.noctime = noctime
|
|
|
+ assert (start is None) == (start_monotonic is None), 'Logic error: if start is given, start_monotonic must be given as well and vice versa.'
|
|
|
if start is None:
|
|
|
start = datetime.utcnow()
|
|
|
+ start_monotonic = time.monotonic()
|
|
|
self.start = start
|
|
|
+ self.start_monotonic = start_monotonic
|
|
|
if end is None:
|
|
|
end = datetime.utcnow()
|
|
|
self.end = end
|
|
@@ -212,7 +215,7 @@ class Archive:
|
|
|
self.chunker = Chunker(self.key.chunk_seed, *chunker_params)
|
|
|
if name in manifest.archives:
|
|
|
raise self.AlreadyExists(name)
|
|
|
- self.last_checkpoint = time.time()
|
|
|
+ self.last_checkpoint = time.monotonic()
|
|
|
i = 0
|
|
|
while True:
|
|
|
self.checkpoint_name = '%s.checkpoint%s' % (name, i and ('.%d' % i) or '')
|
|
@@ -287,9 +290,9 @@ Number of files: {0.stats.nfiles}'''.format(
|
|
|
if self.show_progress:
|
|
|
self.stats.show_progress(item=item, dt=0.2)
|
|
|
self.items_buffer.add(item)
|
|
|
- if time.time() - self.last_checkpoint > self.checkpoint_interval:
|
|
|
+ if time.monotonic() - self.last_checkpoint > self.checkpoint_interval:
|
|
|
self.write_checkpoint()
|
|
|
- self.last_checkpoint = time.time()
|
|
|
+ self.last_checkpoint = time.monotonic()
|
|
|
|
|
|
def write_checkpoint(self):
|
|
|
self.save(self.checkpoint_name)
|
|
@@ -301,14 +304,17 @@ Number of files: {0.stats.nfiles}'''.format(
|
|
|
if name in self.manifest.archives:
|
|
|
raise self.AlreadyExists(name)
|
|
|
self.items_buffer.flush(flush=True)
|
|
|
+ duration = timedelta(seconds=time.monotonic() - self.start_monotonic)
|
|
|
if timestamp is None:
|
|
|
self.end = datetime.utcnow()
|
|
|
+ self.start = self.end - duration
|
|
|
start = self.start
|
|
|
end = self.end
|
|
|
else:
|
|
|
self.end = timestamp
|
|
|
- start = timestamp
|
|
|
- end = timestamp # we only have 1 value
|
|
|
+ self.start = timestamp - duration
|
|
|
+ end = timestamp
|
|
|
+ start = self.start
|
|
|
metadata = StableDict({
|
|
|
'version': 1,
|
|
|
'name': name,
|