| 
					
				 | 
			
			
				@@ -192,30 +192,6 @@ static void postprocess_scenario_result(ScenarioResult* result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Namespace for classes and functions used only in RunScenario 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Using this rather than local definitions to workaround gcc-4.4 limitations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// regarding using templates without linkage 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-namespace runsc { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// ClientContext allocator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static ClientContext* AllocContext(list<ClientContext>* contexts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  contexts->emplace_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  auto context = &contexts->back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  context->set_wait_for_ready(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-struct ServerData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unique_ptr<WorkerService::Stub> stub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unique_ptr<ClientReaderWriter<ServerArgs, ServerStatus>> stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-struct ClientData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unique_ptr<WorkerService::Stub> stub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  unique_ptr<ClientReaderWriter<ClientArgs, ClientStatus>> stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}  // namespace runsc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const ClientConfig& initial_client_config, size_t num_clients, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const ServerConfig& initial_server_config, size_t num_servers, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -225,6 +201,12 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // ClientContext allocations (all are destroyed at scope exit) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   list<ClientContext> contexts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  auto alloc_context = [](list<ClientContext>* contexts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    contexts->emplace_back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    auto context = &contexts->back(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    context->set_wait_for_ready(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // To be added to the result, containing the final configuration used for 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // client and config (including host, etc.) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -277,10 +259,11 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   workers.resize(num_clients + num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Start servers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  using runsc::ServerData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // servers is array rather than std::vector to avoid gcc-4.4 issues 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // where class contained in std::vector must have a copy constructor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  auto* servers = new ServerData[num_servers]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  struct ServerData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unique_ptr<WorkerService::Stub> stub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unique_ptr<ClientReaderWriter<ServerArgs, ServerStatus>> stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::vector<ServerData> servers(num_servers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (size_t i = 0; i < num_servers; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             workers[i].c_str(), i); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -324,8 +307,7 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ServerArgs args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *args.mutable_setup() = server_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    servers[i].stream = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        servers[i].stub->RunServer(runsc::AllocContext(&contexts)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    servers[i].stream = servers[i].stub->RunServer(alloc_context(&contexts)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (!servers[i].stream->Write(args)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_ERROR, "Could not write args to server %zu", i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -343,10 +325,11 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Targets are all set by now 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   result_client_config = client_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Start clients 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  using runsc::ClientData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // clients is array rather than std::vector to avoid gcc-4.4 issues 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // where class contained in std::vector must have a copy constructor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  auto* clients = new ClientData[num_clients]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  struct ClientData { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unique_ptr<WorkerService::Stub> stub; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    unique_ptr<ClientReaderWriter<ClientArgs, ClientStatus>> stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  std::vector<ClientData> clients(num_clients); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   size_t channels_allocated = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (size_t i = 0; i < num_clients; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const auto& worker = workers[i + num_servers]; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -395,8 +378,7 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ClientArgs args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *args.mutable_setup() = per_client_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clients[i].stream = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        clients[i].stub->RunClient(runsc::AllocContext(&contexts)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clients[i].stream = clients[i].stub->RunClient(alloc_context(&contexts)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (!clients[i].stream->Write(args)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_ERROR, "Could not write args to client %zu", i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -516,7 +498,6 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               s.error_message().c_str()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  delete[] clients; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   merged_latencies.FillProto(result->mutable_latencies()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (std::unordered_map<int, int64_t>::iterator it = merged_statuses.begin(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -559,8 +540,6 @@ std::unique_ptr<ScenarioResult> RunScenario( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  delete[] servers; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   postprocess_scenario_result(result.get()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |