Commit
- teach Uploader to set the dmd metadata's last_downloaded_uri to db_entry.last_uploaded_uri - teach Downloader to call did_upload_version properly and set last_uploaded_uri to filecap and set last_downloaded_uri to last_uploaded_uri - fix Downloader remote conflict detection: - conflict "2a" is triggered appropriately for deletion versus modification - conflict "2cii" and "2ciii" shall not be triggered when the version is zero
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -357,8 +357,9 @@ def _maybe_upload(val, now=None): | |
metadata = { 'version': new_version, | ||
'deleted': True, | ||
'last_downloaded_timestamp': last_downloaded_timestamp } | ||
if db_entry.last_downloaded_uri is not None: | ||
metadata['last_downloaded_uri'] = db_entry.last_downloaded_uri | ||
|
||
if db_entry is not None and db_entry.last_uploaded_uri is not None: | ||
metadata['last_downloaded_uri'] = db_entry.last_uploaded_uri | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
david415
Author
Owner
|
||
|
||
empty_uploadable = Data("", self._client.convergence) | ||
d2 = self._upload_dirnode.add_file(encoded_path_u, empty_uploadable, | ||
|
@@ -395,9 +396,7 @@ def _failed(f): | |
return upload_d | ||
elif pathinfo.isfile: | ||
db_entry = self._db.get_db_entry(relpath_u) | ||
|
||
last_downloaded_timestamp = now | ||
|
||
if db_entry is None: | ||
new_version = 0 | ||
elif is_new_file(pathinfo, db_entry): | ||
|
@@ -409,8 +408,8 @@ def _failed(f): | |
|
||
metadata = { 'version': new_version, | ||
'last_downloaded_timestamp': last_downloaded_timestamp } | ||
if db_entry is not None and db_entry.last_downloaded_uri is not None: | ||
metadata['last_downloaded_uri'] = db_entry.last_downloaded_uri | ||
if db_entry is not None and db_entry.last_uploaded_uri is not None: | ||
metadata['last_downloaded_uri'] = db_entry.last_uploaded_uri | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
uploadable = FileName(unicode_from_filepath(fp), self._client.convergence) | ||
d2 = self._upload_dirnode.add_file(encoded_path_u, uploadable, | ||
|
@@ -696,16 +695,17 @@ def _process(self, item, now=None): | |
|
||
def do_update_db(written_abspath_u): | ||
filecap = file_node.get_uri() | ||
last_uploaded_uri = metadata.get('last_uploaded_uri', None) | ||
last_downloaded_uri = filecap | ||
last_downloaded_timestamp = now | ||
last_uploaded_uri = metadata.get('last_uploaded_uri', None) | ||
|
||
written_pathinfo = get_pathinfo(written_abspath_u) | ||
|
||
if not written_pathinfo.exists and not metadata.get('deleted', False): | ||
raise Exception("downloaded object %s disappeared" % quote_local_unicode_path(written_abspath_u)) | ||
|
||
self._db.did_upload_version(relpath_u, metadata['version'], last_uploaded_uri, | ||
last_downloaded_uri, last_downloaded_timestamp, written_pathinfo) | ||
self._db.did_upload_version(relpath_u, metadata['version'], filecap, | ||
last_uploaded_uri, last_downloaded_timestamp, written_pathinfo) | ||
This comment has been minimized.
Sorry, something went wrong.
daira
|
||
self._count('objects_downloaded') | ||
def failed(f): | ||
self._log("download failed: %s" % (str(f),)) | ||
|
@@ -718,20 +718,33 @@ def fail(res): | |
d.addCallback(fail) | ||
else: | ||
pathinfo = get_pathinfo(abspath_u) | ||
|
||
db_entry = self._db.get_db_entry(relpath_u) | ||
dmd_last_downloaded_uri = metadata.get('last_downloaded_uri', None) | ||
|
||
# See <docs/proposed/magic-folder/remote-to-local-sync.rst#conflictoverwrite-decision-algorithm>. | ||
is_conflict_2a = not pathinfo.exists | ||
This comment has been minimized.
Sorry, something went wrong.
daira
|
||
#iii. either dmd_last_downloaded_uri or db_entry.last_uploaded_uri (or both) are absent, or they are different. | ||
print "metadata %r" % (metadata,) | ||
is_conflict_2a = False | ||
if metadata['version'] != 0: | ||
if 'deleted' in metadata.keys(): | ||
This comment has been minimized.
Sorry, something went wrong. |
||
if not pathinfo.exists: | ||
is_conflict_2a = True | ||
This comment has been minimized.
Sorry, something went wrong. |
||
else: | ||
if db_entry is None: | ||
is_conflict_2a = True | ||
|
||
is_conflict_2c_i = self._is_upload_pending(relpath_u) | ||
is_conflict_2c_ii = db_entry is None or is_new_file(pathinfo, db_entry) | ||
is_conflict_2c_iii = (dmd_last_downloaded_uri is None or db_entry is None or db_entry.last_uploaded_uri is None | ||
or dmd_last_downloaded_uri != db_entry.last_uploaded_uri) | ||
if metadata['version'] == 0: | ||
This comment has been minimized.
Sorry, something went wrong.
daira
|
||
is_conflict_2c_ii = False | ||
is_conflict_2c_iii = False | ||
else: | ||
is_conflict_2c_ii = db_entry is None or is_new_file(pathinfo, db_entry) | ||
is_conflict_2c_iii = (dmd_last_downloaded_uri is None or db_entry is None or db_entry.last_uploaded_uri is None | ||
or dmd_last_downloaded_uri != db_entry.last_uploaded_uri) | ||
|
||
print "conflict?", is_conflict_2a, is_conflict_2c_i, is_conflict_2c_ii, is_conflict_2c_iii | ||
|
||
is_conflict = is_conflict_2a or is_conflict_2c_i or is_conflict_2c_ii or is_conflict_2c_iii | ||
|
||
if is_conflict: | ||
self._count('objects_conflicted') | ||
|
||
|
1 comment
on commit 23e76b0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-1; my mistake about the sense of condition 2a is probably confusing things. I suggest reverting this commit then fixing that first, and then fixing the issue I described in 23e76b0#commitcomment-14200290
This is not correct. The intent really is that the
last_downloaded_uri
in the metadata is the URI of the last version downloaded by this client. Thelast_downloaded_uri
field in the database should be set only on downloads, and thelast_uploaded_uri
field should be set only on uploads.If, for example, Alice downloads version x from Bob, then uploads versions x+1 followed by x+2, then the
last_downloaded_uri
in the metadata of version x+2 should be the URI of version x, not the URI of version x+1. This is because a Bob that initially has version x should be able to go directly to version x+2 (which might happen if both uploads happened between two of Bob's scans), and treat that as an overwrite, not a conflict. If, on the other hand, Bob downloads version x+1 first and then version x+2, both of those are still overwrites because theirlast_downloaded_uri
s are both equal to Bob'slast_uploaded_uri
, which is the URI of version x.I think part of the problem with the tests is that
did_upload_version
is incorrectly called for downloads as well as uploads (on line 707 ofmagic_folder.py
).It is more complicated if there are three or more clients. I'm not entirely sure that the conflict detection algorithm works properly in that case, but that should not affect the current tests, all of which use at most two clients.