ImportWorker should use Database.update() instead of Database.save()

Bug #1856111 reported by Jason Gerard DeRose
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Dmedia
Fix Committed
High
Jason Gerard DeRose

Bug Description

microfiber.Database.save() does not retry when there is a conflict (when a doc has been updated in CouchDB out-of-band since the application retrieved it).

microfiber.Database.update() modifies the doc using an update function and then makes its first attempt to save the doc. If there is a conflict, it retrieves the latest version of the doc, modifies it again by calling the update function, and then saves it back.

Currently ImportWorker.import_iter() uses Database.save(), which is fine for when a given file (by content hash) was *not* yet in Dmedia. But when importing a duplicate file, the existing doc must be retrieved, modified, and saved. And if that doc happens to be updated out-of-band in the meantime, the import will bomb out.

Turns out this can happen more often I would have guessed... when importing a large batch of files already in Dmedia. The problem is the window of time between (1) when a re-imported file is moved to its canonical location(s) and (2) when its metadata is updated. During this window the file mtime(s) on disk don't match the MetaData. So if the Dmedia service happens to scan the mtimes during the import and finds an mtime mismatch, it will downgrade that copy, creating the conflicting update. If you are importing to multiple destination drives at once, the chance of hitting this problem gets higher.

Switching ImportWorker.import_iter() to use Database.update() should fix the problem.

Really this bugs shows that the Dmedia service is quickly and aggressively doing the right thing, so there is a bright side :)

Related branches

Changed in dmedia:
status: New → In Progress
importance: Undecided → High
assignee: nobody → Jason Gerard DeRose (jderose)
summary: - ImporterWorker should use Database.update() instead of Database.save()
+ ImportWorker should use Database.update() instead of Database.save()
Changed in dmedia:
status: In Progress → Fix Committed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.