in AdlsDotNetSDK/FileTransfer/Jobs/CopyFileJob.cs [58:124]
protected override object DoJob()
{
long chunkLength = _lengthToRead;
try
{
// If a chunked file was reported to be attempted last transfer and it is resumed, then we have to establish whether we need to transfer any remaining chunks.
// Reason is just based on log file we cannot gurantee the state (Please refer FileTransferCommon.AddFileToConsumerQueue for more doc).
// We need to verify whether the chunk temp file exists or concat temp file exist (for upload) or the destination exist
// to establish where we are in resume. If we are anywhere after "chunk temp file/folder does not exist" state then there is no need of transferring chunks
if (Metadata.IsFileHalfDone)
{
bool notContinue = Metadata.IsUpload ? !Metadata.ResumeUpload(Client) : !Metadata.ResumeDownload();
if (notContinue)
{
// Some irrecoverable problem during resume
if (!string.IsNullOrEmpty(Metadata.UnexpectedTransferErrorResume))
{
return new SingleEntryTransferStatus(Metadata.SrcFile, Metadata.Dest,
Metadata.UnexpectedTransferErrorResume, EntryType.Chunk, SingleChunkStatus.Failed);
}
// Here all the chunks are actually transferred even though it was not reported in logfile
// Here we return success for those cases where we have outstanding jobs for chunks so that they get reported as success in log file
if (Metadata.StartChunksAlreadyTransfered < Metadata.TotalChunks)
{
return new SingleEntryTransferStatus(Metadata.SrcFile, Metadata.Dest, "", EntryType.Chunk, SingleChunkStatus.Successful, ChunkIndex, chunkLength);
}
// This is the case where actually all chunks were already reported to be transferred
return new SingleEntryTransferStatus(Metadata.SrcFile, Metadata.Dest,
"", EntryType.Chunk, SingleChunkStatus.Skipped);
}
}
// Determines whether a chunk of a file need to be skipped. This is more effecient for chunked case because other threads
// do not have to check fileExists again and again. For nonchunked we determine it while creating otherwise there will be two
// filesystem calls
if (ChunkIndex >= 0 && Metadata.ShouldSkipForChunkedFile(Client))
{
return new SingleEntryTransferStatus(Metadata.SrcFile, Metadata.Dest, "", EntryType.File, SingleChunkStatus.Skipped);
}
bool uploadDestExists, downloadDestExists;
// uploadDestExists checks whether the destination exists in remote adl while creating the file
// downloadDestExists checks whether the destination exists in local disk while creating the file
//Either uploadDestExists will be true or downloadDestExists can be true. Both can never be true
// For non chunked job: Determine whether this entry will be skipped while creating the stream, this is why we pass skip flag as output
using (Stream remoteStream = GetRemoteStream(out uploadDestExists),
localStream = GetLocalStream(out downloadDestExists))
{
if (uploadDestExists || downloadDestExists)
{
return new SingleEntryTransferStatus(Metadata.SrcFile, Metadata.Dest, "", EntryType.File, SingleChunkStatus.Skipped);
}
TransferChunks(Metadata.IsUpload ? localStream : remoteStream, Metadata.IsUpload ? remoteStream : localStream);
}
//No need to update the chunk if it is a job for a non-chunked file
if (ChunkIndex >= 0)
{
Metadata.UpdateChunk();
}
return new SingleEntryTransferStatus(Metadata.SrcFile, Destination, "", ChunkIndex >= 0 ? EntryType.Chunk : EntryType.File, SingleChunkStatus.Successful, ChunkIndex, chunkLength);
}
catch (Exception e)
{
return new SingleEntryTransferStatus(Metadata.SrcFile, Destination, e.Message, ChunkIndex >= 0 ? EntryType.Chunk : EntryType.File, SingleChunkStatus.Failed, ChunkIndex, chunkLength);
}
}