protected async Task ReportStatus(HashSet <Guid> operationIDs, long size) { // Wait for a message to appear on the job queue. Console.WriteLine("Waiting for all running jobs to finish."); List <StatusMsg> statuses = new List <StatusMsg>(); DateTimeOffset testStartTime = DateTimeOffset.MaxValue; DateTimeOffset testEndTime = DateTimeOffset.MinValue; while (operationIDs.Count > 0) { CloudQueueMessage rawMessage = await StatusQueue.GetMessageAsync(); while (rawMessage == null) { await Task.Delay(TimeSpan.FromSeconds(1)); rawMessage = await StatusQueue.GetMessageAsync(); } StatusMsg message = null; try { message = DeserializeStatusMessage(rawMessage); } catch (Exception ex) { Console.WriteLine($"[ERROR] Failed to deserialize status message. Details: {ex.Message}"); continue; } finally { await StatusQueue.DeleteMessageAsync(rawMessage); } if (!operationIDs.Contains(message.ID)) { // Consider this a stray message in the queue and skip it. continue; } operationIDs.Remove(message.ID); statuses.Add(message); if (message.StartTime < testStartTime) { testStartTime = message.StartTime; } DateTimeOffset endTime = message.StartTime + message.TestDuration; if (endTime > testEndTime) { testEndTime = endTime; } Console.WriteLine($"...{statuses.Count}/{operationIDs.Count + statuses.Count} jobs have completed."); if (!message.Status) { Console.WriteLine($"[ERROR] Worker {message.ID} failed with status '{message.StatusMessage}'"); } } TimeSpan totalElapsedTime = testEndTime - testStartTime; foreach (StatusMsg status in statuses) { Console.WriteLine($"Worker {status.ID} completed in {status.TestDuration.TotalSeconds} seconds."); } Console.WriteLine($"Test completed in {totalElapsedTime.TotalSeconds} seconds, covering {size} bytes (Averaging {size * 8.0 / 1024 / 1024 / totalElapsedTime.TotalSeconds} Mbps)."); }
public async Task Start(string[] args) { // Parse the arguments. if (!ParseArguments(args, out uint levelOfConcurrency)) { // If invalid arguments were provided, exit the role. return; } // Wait for a message to appear on the job queue. while (true) { Console.WriteLine("Awaiting a job to perform."); CloudQueueMessage rawMessage = await jobQueue_.GetMessageAsync(); while (rawMessage == null) { await Task.Delay(TimeSpan.FromSeconds(1)); rawMessage = await jobQueue_.GetMessageAsync(); } TestMsg message = null; try { message = ConvertQueueMessage(rawMessage); } catch (Exception ex) { // Upon failure to deserialize, log and throw the invalid message away. Console.WriteLine($"[ERROR] Failed to deserialize message. Details: {ex.Message}"); continue; } finally { await jobQueue_.DeleteMessageAsync(rawMessage); } Console.WriteLine("Message received."); CloudBlobContainer container = blobClient_.GetContainerReference(message.Operation.ContainerName); CloudBlockBlob blob = container.GetBlockBlobReference(message.Operation.BlobName); TestOperation operation = message.Operation; if (operation is PutBlobOperation || operation is GetBlobOperation) { // Define the task to be performed. Func <Task <TimeSpan> > executeOperation = null; if (operation is PutBlobOperation) { var detailedOperation = operation as PutBlobOperation; executeOperation = () => { return(UploadBlocksAsync(blobClient_, container, detailedOperation.BlobName, detailedOperation.BlockSizeBytes, detailedOperation.NumBlocks, detailedOperation.StartingBlockId, levelOfConcurrency)); }; } else if (operation is GetBlobOperation) { var detailedOperation = operation as GetBlobOperation; executeOperation = () => { return(GetBlocksAsync(blobClient_, container, detailedOperation.BlobName, detailedOperation.StartIndex, detailedOperation.LengthBytes, detailedOperation.ChunkSizeBytes, levelOfConcurrency)); }; } // Perform the task and report corresponding metrics. DateTimeOffset startTime = DateTimeOffset.UtcNow; StatusMsg statusMessage = null; try { TimeSpan duration = await executeOperation(); statusMessage = new StatusMsg(operation.ID, true, "NA", startTime, duration); } catch (Exception ex) { statusMessage = new StatusMsg(operation.ID, false, ex.Message, startTime, DateTimeOffset.UtcNow - startTime); } finally { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(StatusMsg)); MemoryStream memoryStream = new MemoryStream(); serializer.WriteObject(memoryStream, statusMessage); string messageStr = System.Text.Encoding.Default.GetString(memoryStream.GetBuffer()); messageStr = messageStr.Substring(0, (int)memoryStream.Length); await statusQueue_.AddMessageAsync(new CloudQueueMessage(messageStr)); } } else { Console.WriteLine($"Operation for {message.GetType().FullName} currently unsupported."); } } }