Skip to content

Commit 75c8a55

Browse files
committed
Merge pull request #1251 from koushik-das/CLOUDSTACK-9180
CLOUDSTACK-9180: Optimize concurrent VM deployment operation on same network Check if VR needs to be allocated for a given network and only acquire lock if required Refer to the bug for details. * pr/1251: CLOUDSTACK-9180: Optimize concurrent VM deployment operation on same network Check if VR needs to be allocated for a given network and only acquire lock if required Signed-off-by: Will Stevens <williamstevens@gmail.com>
2 parents 121b3d6 + de89426 commit 75c8a55

2 files changed

Lines changed: 66 additions & 19 deletions

File tree

server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,45 @@ protected void generateDeploymentPlan() {
193193
}
194194

195195
public List<DomainRouterVO> deployVirtualRouter() throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
196-
197196
findOrDeployVirtualRouter();
198-
199197
return nwHelper.startRouters(this);
200198
}
201199

200+
private boolean isRouterDeployed() throws ResourceUnavailableException {
201+
boolean isDeployed = true;
202+
checkPreconditions();
203+
final List<DeployDestination> destinations = findDestinations();
204+
for (final DeployDestination destination : destinations) {
205+
dest = destination;
206+
generateDeploymentPlan();
207+
planDeploymentRouters();
208+
if (getNumberOfRoutersToDeploy() > 0 && prepareDeployment()) {
209+
isDeployed = false;
210+
break;
211+
}
212+
}
213+
return isDeployed;
214+
}
215+
202216
@DB
203217
protected void findOrDeployVirtualRouter() throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
204-
try {
205-
lock();
206-
checkPreconditions();
207-
208-
// dest has pod=null, for Basic Zone findOrDeployVRs for all Pods
209-
final List<DeployDestination> destinations = findDestinations();
210-
211-
for (final DeployDestination destination : destinations) {
212-
dest = destination;
213-
generateDeploymentPlan();
214-
executeDeployment();
218+
if (!isRouterDeployed()) {
219+
try {
220+
lock();
221+
// reset router list that got populated during isRouterDeployed()
222+
routers.clear();
223+
checkPreconditions();
224+
225+
// dest has pod=null, for Basic Zone findOrDeployVRs for all Pods
226+
final List<DeployDestination> destinations = findDestinations();
227+
for (final DeployDestination destination : destinations) {
228+
dest = destination;
229+
generateDeploymentPlan();
230+
executeDeployment();
231+
}
232+
} finally {
233+
unlock();
215234
}
216-
} finally {
217-
unlock();
218235
}
219236
}
220237

@@ -378,7 +395,7 @@ protected void findVirtualProvider() {
378395
final PhysicalNetworkServiceProvider provider = physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString());
379396

380397
if (provider == null) {
381-
throw new CloudRuntimeException(String.format("Cannot find service provider %s in physical network %s", type.toString(), physicalNetworkId));
398+
throw new CloudRuntimeException(String.format("Cannot find service provider %s in physical network %s", type.toString(), physicalNetworkId));
382399
}
383400

384401
vrProvider = vrProviderDao.findByNspIdAndType(provider.getId(), type);

server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTest.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,9 @@ public void testDeployVirtualRouter() throws ConcurrentOperationException,
513513
} finally {
514514
// Assert
515515
verify(deploymentUT, times(1)).lock();
516-
verify(deploymentUT, times(1)).checkPreconditions();
517-
verify(deploymentUT, times(1)).findDestinations();
518-
verify(deploymentUT, times(2)).generateDeploymentPlan();
516+
verify(deploymentUT, times(2)).checkPreconditions();
517+
verify(deploymentUT, times(2)).findDestinations();
518+
verify(deploymentUT, times(3)).generateDeploymentPlan();
519519
verify(deploymentUT, times(2)).executeDeployment();
520520
//verify(deploymentUT, times(2)).planDeploymentRouters();
521521
verify(deploymentUT, times(1)).unlock();
@@ -524,6 +524,36 @@ public void testDeployVirtualRouter() throws ConcurrentOperationException,
524524
fail();
525525
}
526526

527+
@Test
528+
public void testDeployVirtualRouterSkip() throws ConcurrentOperationException,
529+
InsufficientCapacityException, ResourceUnavailableException {
530+
531+
// Prepare
532+
final List<DeployDestination> mockDestinations = new ArrayList<>();
533+
mockDestinations.add(mock(DeployDestination.class));
534+
mockDestinations.add(mock(DeployDestination.class));
535+
536+
final RouterDeploymentDefinition deploymentUT = spy(deployment);
537+
doNothing().when(deploymentUT).checkPreconditions();
538+
doReturn(mockDestinations).when(deploymentUT).findDestinations();
539+
doNothing().when(deploymentUT).planDeploymentRouters();
540+
doNothing().when(deploymentUT).generateDeploymentPlan();
541+
doReturn(0).when(deploymentUT).getNumberOfRoutersToDeploy();
542+
543+
// Execute
544+
try {
545+
deploymentUT.findOrDeployVirtualRouter();
546+
} finally {
547+
// Assert
548+
verify(deploymentUT, times(0)).lock(); // lock shouldn't be acquired when VR already present
549+
verify(deploymentUT, times(1)).checkPreconditions();
550+
verify(deploymentUT, times(1)).findDestinations();
551+
verify(deploymentUT, times(2)).generateDeploymentPlan();
552+
verify(deploymentUT, times(0)).executeDeployment(); // no need to deploy VR as already present
553+
verify(deploymentUT, times(0)).unlock(); // same as lock
554+
}
555+
}
556+
527557
@Test
528558
public void testGetNumberOfRoutersToDeploy() {
529559
// Prepare

0 commit comments

Comments
 (0)