Commit ca5cb660 authored by mariannet's avatar mariannet Committed by Commit Bot

Cloud import: enable retry upon failure with the affected items.

When backing up things via cloud import, they first get snapshotted locally
before being synced to drive. If there is not enough local space for the
snapshot, backup for the affected file fails. However, sync to drive is the
bottleneck to the whole operation, so backing up a sum of files whose size
exceeds the storage available locally might have a couple of them failing. This
shouldn't affect the user, though - so wait until drive sends a sync complete
signal, then retry backing up the failed items, as long as at least one file is
backed up successfully and at least one of them fails.

Cloud import / Infini backup: Enable retry upon failure with the affected items.

Bug: 354574
Test: manual + ./out/Release/browser_tests --gtest_filter=*MediaImportHandler*
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Id29217980f7d42e7137fdb00fa7f508e1ab0c85d
Reviewed-on: https://chromium-review.googlesource.com/789171
Commit-Queue: Marianne Thieffry <mariannet@google.com>
Reviewed-by: default avatarSteve McKay <smckay@chromium.org>
Reviewed-by: default avatarNaoki Fukino <fukino@chromium.org>
Reviewed-by: default avatarTomasz Mikolajewski <mtomasz@chromium.org>
Reviewed-by: default avatarKeigo Oka <oka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520885}
parent 1b09e229
...@@ -647,6 +647,9 @@ ...@@ -647,6 +647,9 @@
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_STATUS_DONE" desc="Cloud import backup is complete status."> <message name="IDS_FILE_BROWSER_CLOUD_IMPORT_STATUS_DONE" desc="Cloud import backup is complete status.">
<ph name="FILE_COUNT">$1<ex>5</ex></ph> photos backed up to <ph name="BEGIN_LINK">&lt;a is='action-link' class='destination-link'&gt;</ph>Google Drive<ph name="END_LINK">&lt;/a&gt;</ph> <ph name="FILE_COUNT">$1<ex>5</ex></ph> photos backed up to <ph name="BEGIN_LINK">&lt;a is='action-link' class='destination-link'&gt;</ph>Google Drive<ph name="END_LINK">&lt;/a&gt;</ph>
</message> </message>
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_ERROR_ITEM" desc="Cloud import error message for a file it couldn't back up.">
Couldn't back up <ph name="FILE_NAME">$1<ex>photo.jpg</ex></ph>
</message>
<message name="IDS_FILE_BROWSER_CLOUD_IMPORT_TOOLTIP_DONE" desc="Cloud import backup is complete tooltip."> <message name="IDS_FILE_BROWSER_CLOUD_IMPORT_TOOLTIP_DONE" desc="Cloud import backup is complete tooltip.">
<ph name="FILE_COUNT">$1<ex>5</ex></ph> photos backed up <ph name="FILE_COUNT">$1<ex>5</ex></ph> photos backed up
</message> </message>
......
...@@ -309,6 +309,8 @@ void AddStringsForCloudImport(base::DictionaryValue* dict) { ...@@ -309,6 +309,8 @@ void AddStringsForCloudImport(base::DictionaryValue* dict) {
SET_STRING("CLOUD_IMPORT_COMMAND", IDS_FILE_BROWSER_CLOUD_IMPORT_COMMAND); SET_STRING("CLOUD_IMPORT_COMMAND", IDS_FILE_BROWSER_CLOUD_IMPORT_COMMAND);
SET_STRING("CLOUD_IMPORT_CANCEL_COMMAND", SET_STRING("CLOUD_IMPORT_CANCEL_COMMAND",
IDS_FILE_BROWSER_CLOUD_IMPORT_CANCEL_COMMAND); IDS_FILE_BROWSER_CLOUD_IMPORT_CANCEL_COMMAND);
SET_STRING("CLOUD_IMPORT_ERROR_ITEM",
IDS_FILE_BROWSER_CLOUD_IMPORT_ERROR_ITEM);
SET_STRING("CLOUD_IMPORT_STATUS_READY", SET_STRING("CLOUD_IMPORT_STATUS_READY",
IDS_FILE_BROWSER_CLOUD_IMPORT_STATUS_DONE); IDS_FILE_BROWSER_CLOUD_IMPORT_STATUS_DONE);
......
...@@ -79,10 +79,8 @@ function FileBrowserBackgroundImpl() { ...@@ -79,10 +79,8 @@ function FileBrowserBackgroundImpl() {
* @type {!importer.MediaImportHandler} * @type {!importer.MediaImportHandler}
*/ */
this.mediaImportHandler = new importer.MediaImportHandler( this.mediaImportHandler = new importer.MediaImportHandler(
this.progressCenter, this.progressCenter, this.historyLoader, this.dispositionChecker_,
this.historyLoader, this.tracker, this.driveSyncHandler);
this.dispositionChecker_,
this.tracker);
/** /**
* String assets. * String assets.
......
...@@ -174,6 +174,7 @@ ...@@ -174,6 +174,7 @@
'../../../externs/background/compiled_resources2.gyp:import_runner', '../../../externs/background/compiled_resources2.gyp:import_runner',
'../../common/js/compiled_resources2.gyp:importer_common', '../../common/js/compiled_resources2.gyp:importer_common',
'../../common/js/compiled_resources2.gyp:metrics', '../../common/js/compiled_resources2.gyp:metrics',
'drive_sync_handler',
'import_history', 'import_history',
'media_scanner', 'media_scanner',
'progress_center', 'progress_center',
......
...@@ -25,8 +25,10 @@ ...@@ -25,8 +25,10 @@
<script src="../../common/js/progress_center_common.js"></script> <script src="../../common/js/progress_center_common.js"></script>
<script src="../../common/js/test_tracker.js"></script> <script src="../../common/js/test_tracker.js"></script>
<script src="drive_sync_handler.js"></script>
<script src="entry_location_impl.js"></script> <script src="entry_location_impl.js"></script>
<script src="test_import_history.js"></script> <script src="test_import_history.js"></script>
<script src="mock_drive_sync_handler.js"></script>
<script src="mock_progress_center.js"></script> <script src="mock_progress_center.js"></script>
<script src="mock_media_scanner.js"></script> <script src="mock_media_scanner.js"></script>
<script src="mock_volume_manager.js"></script> <script src="mock_volume_manager.js"></script>
......
...@@ -32,6 +32,9 @@ var duplicateFinderFactory; ...@@ -32,6 +32,9 @@ var duplicateFinderFactory;
/** @type {!Promise<!DirectoryEntry>} */ /** @type {!Promise<!DirectoryEntry>} */
var destinationFactory; var destinationFactory;
/** @type {!MockDriveSyncHandler} */
var driveSyncHandler;
// Set up string assets. // Set up string assets.
loadTimeData.data = { loadTimeData.data = {
CLOUD_IMPORT_ITEMS_REMAINING: '', CLOUD_IMPORT_ITEMS_REMAINING: '',
...@@ -90,14 +93,12 @@ function setUp() { ...@@ -90,14 +93,12 @@ function setUp() {
destinationFileSystem = new MockFileSystem('googleDriveFilesystem'); destinationFileSystem = new MockFileSystem('googleDriveFilesystem');
destinationFactory = Promise.resolve(destinationFileSystem.root); destinationFactory = Promise.resolve(destinationFileSystem.root);
duplicateFinderFactory = new importer.TestDuplicateFinder.Factory(); duplicateFinderFactory = new importer.TestDuplicateFinder.Factory();
driveSyncHandler = new MockDriveSyncHandler();
mediaImporter = new importer.MediaImportHandler( mediaImporter = new importer.MediaImportHandler(
progressCenter, progressCenter, importHistory, function(entry, destination) {
importHistory,
function(entry, destination) {
return dispositionChecker(entry, destination); return dispositionChecker(entry, destination);
}, }, new TestTracker(), driveSyncHandler);
new TestTracker());
} }
function testImportMedia(callback) { function testImportMedia(callback) {
...@@ -167,10 +168,8 @@ function testImportMedia_skipAndMarkDuplicatedFiles(callback) { ...@@ -167,10 +168,8 @@ function testImportMedia_skipAndMarkDuplicatedFiles(callback) {
return Promise.resolve(importer.Disposition.ORIGINAL); return Promise.resolve(importer.Disposition.ORIGINAL);
}; };
mediaImporter = new importer.MediaImportHandler( mediaImporter = new importer.MediaImportHandler(
progressCenter, progressCenter, importHistory, dispositionChecker, new TestTracker(),
importHistory, driveSyncHandler);
dispositionChecker,
new TestTracker());
var scanResult = new TestScanResult(media); var scanResult = new TestScanResult(media);
var importTask = mediaImporter.importFromScanResult( var importTask = mediaImporter.importFromScanResult(
scanResult, scanResult,
...@@ -564,7 +563,7 @@ function testImportWithErrors(callback) { ...@@ -564,7 +563,7 @@ function testImportWithErrors(callback) {
} }
}); });
// Verify that the error didn't result in only 3 files being imported. // Verify that the error didn't result in some files not being copied.
reportPromise( reportPromise(
whenImportDone.then( whenImportDone.then(
function() { function() {
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* Mock of DriveSyncHandler.
* @constructor
* @struct
*/
function MockDriveSyncHandler() {}
MockDriveSyncHandler.prototype = {
__proto__: cr.EventTarget.prototype,
};
...@@ -222,10 +222,14 @@ TestScanResult.prototype.canceled = function() { ...@@ -222,10 +222,14 @@ TestScanResult.prototype.canceled = function() {
/** @override */ /** @override */
TestScanResult.prototype.getStatistics = function() { TestScanResult.prototype.getStatistics = function() {
duplicates = {};
duplicates[importer.Disposition.CONTENT_DUPLICATE] = 0;
duplicates[importer.Disposition.HISTORY_DUPLICATE] = 0;
duplicates[importer.Disposition.SCAN_DUPLICATE] = 0;
return { return {
scanDuration: this.scanDuration, scanDuration: this.scanDuration,
newFileCount: this.fileEntries.length, newFileCount: this.fileEntries.length,
duplicates: {}, duplicates: duplicates,
sizeBytes: this.totalBytes sizeBytes: this.totalBytes
}; };
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment