Fixed: File imports on cloud drives slow due to transaction logic
This commit is contained in:
parent
e28b2e8328
commit
95d64208d0
|
@ -20,15 +20,37 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
||||||
private readonly string _nfsFile = ".nfs01231232";
|
private readonly string _nfsFile = ".nfs01231232";
|
||||||
|
|
||||||
|
private MockMount _sourceMount;
|
||||||
|
private MockMount _targetMount;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IDiskProvider>(MockBehavior.Strict);
|
Mocker.GetMock<IDiskProvider>(MockBehavior.Strict);
|
||||||
|
|
||||||
|
_sourceMount = new MockMount()
|
||||||
|
{
|
||||||
|
Name = "source",
|
||||||
|
RootDirectory = @"C:\source".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
_targetMount = new MockMount()
|
||||||
|
{
|
||||||
|
Name = "target",
|
||||||
|
RootDirectory = @"C:\target".AsOsAgnostic()
|
||||||
|
};
|
||||||
|
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(v => v.GetMount(It.IsAny<string>()))
|
.Setup(v => v.GetMount(It.IsAny<string>()))
|
||||||
.Returns((IMount)null);
|
.Returns((IMount)null);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.GetMount(It.Is<string>(p => p.StartsWith(_sourceMount.RootDirectory))))
|
||||||
|
.Returns(_sourceMount);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(v => v.GetMount(It.Is<string>(p => p.StartsWith(_targetMount.RootDirectory))))
|
||||||
|
.Returns(_targetMount);
|
||||||
|
|
||||||
WithEmulatedDiskProvider();
|
WithEmulatedDiskProvider();
|
||||||
|
|
||||||
WithExistingFile(_sourcePath);
|
WithExistingFile(_sourcePath);
|
||||||
|
@ -58,6 +80,27 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("fuse.mergerfs")]
|
||||||
|
[TestCase("fuse.rclone")]
|
||||||
|
[TestCase("mergerfs")]
|
||||||
|
[TestCase("rclone")]
|
||||||
|
public void should_not_use_verified_transfer_on_specific_filesystems(string fs)
|
||||||
|
{
|
||||||
|
MonoOnly();
|
||||||
|
|
||||||
|
_targetMount.DriveFormat = fs;
|
||||||
|
|
||||||
|
Subject.VerificationMode.Should().Be(DiskTransferVerificationMode.VerifyOnly);
|
||||||
|
|
||||||
|
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.TryCreateHardLink(_sourcePath, _backupPath), Times.Never());
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_throw_if_path_is_the_same()
|
public void should_throw_if_path_is_the_same()
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.IO;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Test.DiskTests
|
||||||
|
{
|
||||||
|
public class MockMount : IMount
|
||||||
|
{
|
||||||
|
public long AvailableFreeSpace { get; set; }
|
||||||
|
|
||||||
|
public string DriveFormat { get; set; }
|
||||||
|
|
||||||
|
public DriveType DriveType { get; set; } = DriveType.Fixed;
|
||||||
|
|
||||||
|
public bool IsReady { get; set; } = true;
|
||||||
|
|
||||||
|
public MountOptions MountOptions { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string RootDirectory { get; set; }
|
||||||
|
|
||||||
|
public long TotalFreeSpace { get; set; }
|
||||||
|
|
||||||
|
public long TotalSize { get; set; }
|
||||||
|
|
||||||
|
public string VolumeLabel { get; set; }
|
||||||
|
|
||||||
|
public string VolumeName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -288,15 +288,31 @@ namespace NzbDrone.Common.Disk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We force a transactional transfer if the transfer occurs between mounts and one of the mounts is cifs, it would be a copy anyway.
|
// Adjust the transfer mode depending on the filesystems
|
||||||
if (verificationMode == DiskTransferVerificationMode.TryTransactional && OsInfo.IsNotWindows)
|
if (verificationMode == DiskTransferVerificationMode.TryTransactional)
|
||||||
{
|
{
|
||||||
var sourceMount = _diskProvider.GetMount(sourcePath);
|
var sourceMount = _diskProvider.GetMount(sourcePath);
|
||||||
var targetMount = _diskProvider.GetMount(targetPath);
|
var targetMount = _diskProvider.GetMount(targetPath);
|
||||||
|
|
||||||
if (sourceMount != null && targetMount != null && sourceMount.RootDirectory != targetMount.RootDirectory &&
|
var isSameMount = (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory);
|
||||||
(sourceMount.DriveFormat == "cifs" || targetMount.DriveFormat == "cifs"))
|
|
||||||
|
var sourceDriveFormat = sourceMount?.DriveFormat ?? string.Empty;
|
||||||
|
var targetDriveFormat = targetMount?.DriveFormat ?? string.Empty;
|
||||||
|
|
||||||
|
if (isSameMount)
|
||||||
{
|
{
|
||||||
|
// No transaction needed for operations on same mount, force VerifyOnly
|
||||||
|
verificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||||
|
}
|
||||||
|
else if (sourceDriveFormat.Contains("mergerfs") || sourceDriveFormat.Contains("rclone") ||
|
||||||
|
targetDriveFormat.Contains("mergerfs") || targetDriveFormat.Contains("rclone"))
|
||||||
|
{
|
||||||
|
// Cloud storage filesystems don't need any Transactional stuff and it hurts performance, force VerifyOnly
|
||||||
|
verificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||||
|
}
|
||||||
|
else if ((sourceDriveFormat == "cifs" || targetDriveFormat == "cifs") && OsInfo.IsNotWindows)
|
||||||
|
{
|
||||||
|
// Force Transactional on a cifs mount due to the likeliness of move failures on certain scenario's on mono
|
||||||
verificationMode = DiskTransferVerificationMode.Transactional;
|
verificationMode = DiskTransferVerificationMode.Transactional;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue