/// <summary> /// Puts the benchmark results of the given experiment to the storage. /// </summary> /// <param name="results">All results must have same experiment id. /// <returns>Blob etag, if results have been uploaded. /// Null, if the precondition failed and nothing was uploaded.</returns> public async Task <string> PutAzureExperimentResults(int expId, AzureBenchmarkResult[] results, UploadBlobMode mode, string etag = null) { string fileName = GetResultsFileName(expId); using (MemoryStream zipStream = new MemoryStream()) { using (var zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true)) { var entry = zip.CreateEntry(fileName); AzureBenchmarkResult.SaveBenchmarks(results, entry.Open()); } zipStream.Position = 0; return(await UploadBlobAsync(resultsContainer, GetResultBlobName(expId), zipStream, mode, etag)); } }
/// <summary> /// If blob uploaded, returns its etag; otherwise, if precondition failed for the mode, returns null. /// </summary> private static async Task <string> UploadBlobAsync(CloudBlobContainer container, string blobName, Stream content, UploadBlobMode mode, string etag = null) { if (mode == UploadBlobMode.ReplaceExact && etag == null) { throw new ArgumentException("Etag must be provided when using ReplaceExact mode"); } try { var stdoutBlob = container.GetBlockBlobReference(blobName); AccessCondition accessCondition; switch (mode) { case UploadBlobMode.CreateNew: accessCondition = AccessCondition.GenerateIfNotExistsCondition(); break; case UploadBlobMode.CreateOrReplace: accessCondition = AccessCondition.GenerateEmptyCondition(); break; case UploadBlobMode.ReplaceExact: accessCondition = AccessCondition.GenerateIfMatchCondition(etag); break; default: throw new ArgumentException("Unknown mode"); } await stdoutBlob.UploadFromStreamAsync(content, accessCondition, new BlobRequestOptions() { RetryPolicy = new Microsoft.WindowsAzure.Storage.RetryPolicies.ExponentialRetry(TimeSpan.FromMilliseconds(100), 14) }, null); return(stdoutBlob.Properties.ETag); } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) { return(null); } catch (StorageException ex) { Trace.WriteLine(string.Format("Failed to upload text to the blob: {0}, blob name: {1}, response code: {2}", ex.Message, blobName, ex.RequestInformation.HttpStatusCode)); throw; } }