public async Task <HttpResponseMessage> UploadFileAsync( long containerId, string itemPath, Stream fileStream, Guid scopeIdentifier, CancellationToken cancellationToken, int chunkSize) { return(await _client.UploadFileAsync(containerId, itemPath, fileStream, scopeIdentifier, cancellationToken, chunkSize : chunkSize)); }
private async Task ParallelUploadAsync(IAsyncCommandContext context, int uploaderId, CancellationToken token) { string fileToUpload; Stopwatch uploadTimer = new Stopwatch(); while (_fileUploadQueue.TryDequeue(out fileToUpload)) { token.ThrowIfCancellationRequested(); try { context.Output(StringUtil.Loc("StartFileUpload", fileToUpload, new FileInfo(fileToUpload).Length)); using (FileStream fs = File.Open(fileToUpload, FileMode.Open, FileAccess.Read)) { string itemPath = (_containerPath.TrimEnd('/') + "/" + fileToUpload.Remove(0, _sourceParentDirectory.Length + 1)).Replace('\\', '/'); uploadTimer.Restart(); HttpResponseMessage response = null; try { response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, token); } catch (OperationCanceledException) when(token.IsCancellationRequested) { context.Output(StringUtil.Loc("FileUploadCancelled", fileToUpload)); throw; } catch (Exception ex) { context.Output(StringUtil.Loc("FileUploadFailed", fileToUpload, ex.Message)); throw; } uploadTimer.Stop(); if (response.StatusCode != System.Net.HttpStatusCode.Created) { throw new Exception(StringUtil.Loc("FileContainerUploadFailed", response.StatusCode, response.ReasonPhrase, fileToUpload, itemPath)); } else { context.Output(StringUtil.Loc("FileUploadFinish", fileToUpload, uploadTimer.ElapsedMilliseconds)); } } Interlocked.Increment(ref _filesUploaded); } catch (Exception ex) when(!(ex is OperationCanceledException)) { _exceptionsDuringFileUpload.Add(ex); _uploadCancellationTokenSource.Cancel(); return; } } }
private async Task <List <string> > UploadAsync(IAsyncCommandContext context, int uploaderId, CancellationToken token) { List <string> failedFiles = new List <string>(); string fileToUpload; Stopwatch uploadTimer = new Stopwatch(); while (_fileUploadQueue.TryDequeue(out fileToUpload)) { token.ThrowIfCancellationRequested(); try { using (FileStream fs = File.Open(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read)) { string itemPath = (_containerPath.TrimEnd('/') + "/" + fileToUpload.Remove(0, _sourceParentDirectory.Length + 1)).Replace('\\', '/'); uploadTimer.Restart(); bool catchExceptionDuringUpload = false; HttpResponseMessage response = null; try { response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, cancellationToken : token, chunkSize : 4 * 1024 * 1024); } catch (OperationCanceledException) when(token.IsCancellationRequested) { context.Output(StringUtil.Loc("FileUploadCancelled", fileToUpload)); if (response != null) { response.Dispose(); response = null; } throw; } catch (Exception ex) { catchExceptionDuringUpload = true; context.Output(StringUtil.Loc("FileUploadFailed", fileToUpload, ex.Message)); context.Output(ex.ToString()); } uploadTimer.Stop(); if (catchExceptionDuringUpload || (response != null && response.StatusCode != HttpStatusCode.Created)) { if (response != null) { context.Output(StringUtil.Loc("FileContainerUploadFailed", response.StatusCode, response.ReasonPhrase, fileToUpload, itemPath)); } // output detail upload trace for the file. ConcurrentQueue <string> logQueue; if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue)) { context.Output(StringUtil.Loc("FileUploadDetailTrace", itemPath)); string message; while (logQueue.TryDequeue(out message)) { context.Output(message); } } // tracking file that failed to upload. failedFiles.Add(fileToUpload); } else { context.Debug(StringUtil.Loc("FileUploadFinish", fileToUpload, uploadTimer.ElapsedMilliseconds)); // debug detail upload trace for the file. ConcurrentQueue <string> logQueue; if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue)) { context.Debug($"Detail upload trace for file: {itemPath}"); string message; while (logQueue.TryDequeue(out message)) { context.Debug(message); } } } if (response != null) { response.Dispose(); response = null; } } Interlocked.Increment(ref _filesProcessed); } catch (Exception ex) { context.Output(StringUtil.Loc("FileUploadFileOpenFailed", ex.Message, fileToUpload)); throw ex; } } return(failedFiles); }
private async Task <UploadResult> UploadAsync(RunnerActionPluginExecutionContext context, int uploaderId, CancellationToken token) { List <string> failedFiles = new List <string>(); long uploadedSize = 0; string fileToUpload; Stopwatch uploadTimer = new Stopwatch(); while (_fileUploadQueue.TryDequeue(out fileToUpload)) { token.ThrowIfCancellationRequested(); try { using (FileStream fs = File.Open(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read)) { string itemPath = (_containerPath.TrimEnd('/') + "/" + fileToUpload.Remove(0, _sourceParentDirectory.Length + 1)).Replace('\\', '/'); bool failAndExit = false; try { uploadTimer.Restart(); using (HttpResponseMessage response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, cancellationToken: token, chunkSize: 4 * 1024 * 1024)) { if (response == null || response.StatusCode != HttpStatusCode.Created) { context.Output($"Unable to copy file to server StatusCode={response?.StatusCode}: {response?.ReasonPhrase}. Source file path: {fileToUpload}. Target server path: {itemPath}"); if (response?.StatusCode == HttpStatusCode.Conflict) { // fail upload task but continue with any other files context.Error($"Error '{fileToUpload}' has already been uploaded."); } else if (_fileContainerHttpClient.IsFastFailResponse(response)) { // Fast fail: we received an http status code where we should abandon our efforts context.Output($"Cannot continue uploading files, so draining upload queue of {_fileUploadQueue.Count} items."); DrainUploadQueue(context); failedFiles.Clear(); failAndExit = true; throw new UploadFailedException($"Critical failure uploading '{fileToUpload}'"); } else { context.Debug($"Adding '{fileToUpload}' to retry list."); failedFiles.Add(fileToUpload); } throw new UploadFailedException($"Http failure response '{response?.StatusCode}': '{response?.ReasonPhrase}' while uploading '{fileToUpload}'"); } uploadTimer.Stop(); context.Debug($"File: '{fileToUpload}' took {uploadTimer.ElapsedMilliseconds} milliseconds to finish upload"); uploadedSize += fs.Length; OutputLogForFile(context, fileToUpload, $"Detail upload trace for file: {itemPath}", context.Debug); } } catch (OperationCanceledException) when(token.IsCancellationRequested) { context.Output($"File upload has been cancelled during upload file: '{fileToUpload}'."); throw; } catch (Exception ex) { context.Output($"Fail to upload '{fileToUpload}' due to '{ex.Message}'."); context.Output(ex.ToString()); OutputLogForFile(context, fileToUpload, $"Detail upload trace for file that fail to upload: {itemPath}", context.Output); if (failAndExit) { context.Debug("Exiting upload."); throw; } } } Interlocked.Increment(ref _uploadFilesProcessed); } catch (Exception ex) { context.Output($"File error '{ex.Message}' when uploading file '{fileToUpload}'."); throw; } } return(new UploadResult(failedFiles, uploadedSize)); }