in AdlsDotNetSDK/AdlsOutputStream.cs [397:443]
private async Task WriteServiceAsync(SyncFlag flag, CancellationToken cancelToken)
{
if (BufferSize == 0 && (flag == SyncFlag.DATA || (MetaDataSynced && flag == SyncFlag.METADATA)))
{
return;
}
if (OutStreamLog.IsTraceEnabled)
{
OutStreamLog.Trace($"ADLFileOutputStream, Stream flush of size {BufferSize} at offset {FilePointer} for file {Filename} for client {Client.ClientId}");
}
OperationResponse resp = new OperationResponse();
await Core.AppendAsync(Filename, LeaseId, LeaseId, flag, FilePointer, Buffer, 0, BufferSize, Client, new RequestOptions(Client.GetPerRequestTimeout(), new ExponentialRetryPolicy()), resp, cancelToken).ConfigureAwait(false);
if (!resp.IsSuccessful)
{
// if this was a retry and we get bad offset, then this might be because we got a transient
// failure on first try, but request succeeded on back-end. In that case, the retry would fail
// with bad offset. To detect that, we check if there was a retry done, and if the current error we
// have is bad offset.
// If so, do a zero-length append at the current expected Offset, and if that succeeds,
// then the file length must be good - swallow the error. If this append fails, then the last append
// did not succeed and we have some other offset on server - bubble up the error.
if (resp.Retries > 0 && resp.HttpStatus == HttpStatusCode.BadRequest &&
resp.RemoteExceptionName.Equals("BadOffsetException"))
{
bool zeroAppendIsSuccesful = await PerformZeroLengthAppendAsync(FilePointer + BufferSize, flag, cancelToken).ConfigureAwait(false);
if (zeroAppendIsSuccesful)
{
if (OutStreamLog.IsDebugEnabled)
{
OutStreamLog.Debug($"ADLFileOutputStream, Zero size Append succeded and the expected FileSize is {FilePointer + BufferSize}, ignoring BadOffsetException for session {LeaseId} for file {Filename} for client {Client.ClientId}");
}
FilePointer += BufferSize;
BufferSize = 0;
MetaDataSynced = flag == SyncFlag.METADATA;
return;
}
if (OutStreamLog.IsDebugEnabled)
{
OutStreamLog.Debug($"ADLFileOutputStream, Append failed at offset {FilePointer} for session {LeaseId} for file {Filename} for client {Client.ClientId}");
}
}
throw Client.GetExceptionFromResponse(resp, $"Error in appending for file {Filename} at offset {FilePointer}.");
}
MetaDataSynced = flag == SyncFlag.METADATA;//Make sure if metadata is already updated, then do not try to update metada again unless data has been written
FilePointer += BufferSize;//Update the filepointer as data is written to server
BufferSize = 0;//Resets buffersize since all data in buffer is flushed to server
}