MAPREDUCE-2953. Fix a race condition on submission which caused client to incorrectly assume application was gone by making submission synchronous for RMAppManager. Contributed by Thomas Graves.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1166968 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a0ef2d7503
commit
ca853445e9
|
@ -1247,6 +1247,10 @@ Release 0.23.0 - Unreleased
|
||||||
MAPREDUCE-2937. Ensure reason for application failure is displayed to the
|
MAPREDUCE-2937. Ensure reason for application failure is displayed to the
|
||||||
user. (mahadev via acmurthy)
|
user. (mahadev via acmurthy)
|
||||||
|
|
||||||
|
MAPREDUCE-2953. Fix a race condition on submission which caused client to
|
||||||
|
incorrectly assume application was gone by making submission synchronous
|
||||||
|
for RMAppManager. (Thomas Graves via acmurthy)
|
||||||
|
|
||||||
Release 0.22.0 - Unreleased
|
Release 0.22.0 - Unreleased
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class ClientRMService extends AbstractService implements
|
||||||
final private YarnScheduler scheduler;
|
final private YarnScheduler scheduler;
|
||||||
final private RMContext rmContext;
|
final private RMContext rmContext;
|
||||||
private final AMLivelinessMonitor amLivelinessMonitor;
|
private final AMLivelinessMonitor amLivelinessMonitor;
|
||||||
|
private final RMAppManager rmAppManager;
|
||||||
|
|
||||||
private String clientServiceBindAddress;
|
private String clientServiceBindAddress;
|
||||||
private Server server;
|
private Server server;
|
||||||
|
@ -100,11 +101,13 @@ public class ClientRMService extends AbstractService implements
|
||||||
private ApplicationACLsManager aclsManager;
|
private ApplicationACLsManager aclsManager;
|
||||||
private Map<ApplicationACL, AccessControlList> applicationACLs;
|
private Map<ApplicationACL, AccessControlList> applicationACLs;
|
||||||
|
|
||||||
public ClientRMService(RMContext rmContext, YarnScheduler scheduler) {
|
public ClientRMService(RMContext rmContext, YarnScheduler scheduler,
|
||||||
|
RMAppManager rmAppManager) {
|
||||||
super(ClientRMService.class.getName());
|
super(ClientRMService.class.getName());
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.rmContext = rmContext;
|
this.rmContext = rmContext;
|
||||||
this.amLivelinessMonitor = rmContext.getAMLivelinessMonitor();
|
this.amLivelinessMonitor = rmContext.getAMLivelinessMonitor();
|
||||||
|
this.rmAppManager = rmAppManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -201,8 +204,10 @@ public class ClientRMService extends AbstractService implements
|
||||||
throw new IOException("Application with id " + applicationId
|
throw new IOException("Application with id " + applicationId
|
||||||
+ " is already present! Cannot add a duplicate!");
|
+ " is already present! Cannot add a duplicate!");
|
||||||
}
|
}
|
||||||
this.rmContext.getDispatcher().getEventHandler().handle(
|
// This needs to be synchronous as the client can query
|
||||||
new RMAppManagerSubmitEvent(submissionContext));
|
// immediately following the submission to get the application status.
|
||||||
|
// So call handle directly and do not send an event.
|
||||||
|
rmAppManager.handle(new RMAppManagerSubmitEvent(submissionContext));
|
||||||
|
|
||||||
LOG.info("Application with id " + applicationId.getId() +
|
LOG.info("Application with id " + applicationId.getId() +
|
||||||
" submitted by user " + user + " with " + submissionContext);
|
" submitted by user " + user + " with " + submissionContext);
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class RMAppManager implements EventHandler<RMAppManagerEvent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void submitApplication(ApplicationSubmissionContext submissionContext) {
|
protected synchronized void submitApplication(ApplicationSubmissionContext submissionContext) {
|
||||||
ApplicationId applicationId = submissionContext.getApplicationId();
|
ApplicationId applicationId = submissionContext.getApplicationId();
|
||||||
RMApp application = null;
|
RMApp application = null;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class ResourceManager extends CompositeService implements Recoverable {
|
||||||
protected NMLivelinessMonitor nmLivelinessMonitor;
|
protected NMLivelinessMonitor nmLivelinessMonitor;
|
||||||
protected NodesListManager nodesListManager;
|
protected NodesListManager nodesListManager;
|
||||||
private SchedulerEventDispatcher schedulerDispatcher;
|
private SchedulerEventDispatcher schedulerDispatcher;
|
||||||
private RMAppManager rmAppManager;
|
protected RMAppManager rmAppManager;
|
||||||
|
|
||||||
private final AtomicBoolean shutdown = new AtomicBoolean(false);
|
private final AtomicBoolean shutdown = new AtomicBoolean(false);
|
||||||
private WebApp webApp;
|
private WebApp webApp;
|
||||||
|
@ -176,14 +176,14 @@ public class ResourceManager extends CompositeService implements Recoverable {
|
||||||
masterService = createApplicationMasterService();
|
masterService = createApplicationMasterService();
|
||||||
addService(masterService) ;
|
addService(masterService) ;
|
||||||
|
|
||||||
clientRM = createClientRMService();
|
|
||||||
addService(clientRM);
|
|
||||||
|
|
||||||
this.rmAppManager = createRMAppManager();
|
this.rmAppManager = createRMAppManager();
|
||||||
// Register event handler for RMAppManagerEvents
|
// Register event handler for RMAppManagerEvents
|
||||||
this.rmDispatcher.register(RMAppManagerEventType.class,
|
this.rmDispatcher.register(RMAppManagerEventType.class,
|
||||||
this.rmAppManager);
|
this.rmAppManager);
|
||||||
|
|
||||||
|
clientRM = createClientRMService();
|
||||||
|
addService(clientRM);
|
||||||
|
|
||||||
adminService = createAdminService();
|
adminService = createAdminService();
|
||||||
addService(adminService);
|
addService(adminService);
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ public class ResourceManager extends CompositeService implements Recoverable {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ClientRMService createClientRMService() {
|
protected ClientRMService createClientRMService() {
|
||||||
return new ClientRMService(this.rmContext, scheduler);
|
return new ClientRMService(this.rmContext, scheduler, this.rmAppManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ApplicationMasterService createApplicationMasterService() {
|
protected ApplicationMasterService createApplicationMasterService() {
|
||||||
|
|
|
@ -60,13 +60,9 @@ public class MockRM extends ResourceManager {
|
||||||
|
|
||||||
public void waitForState(ApplicationId appId, RMAppState finalState)
|
public void waitForState(ApplicationId appId, RMAppState finalState)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
RMApp app = getRMContext().getRMApps().get(appId);
|
||||||
|
Assert.assertNotNull("app shouldn't be null", app);
|
||||||
int timeoutSecs = 0;
|
int timeoutSecs = 0;
|
||||||
RMApp app = null;
|
|
||||||
while ((app == null) && timeoutSecs++ < 20) {
|
|
||||||
app = getRMContext().getRMApps().get(appId);
|
|
||||||
Thread.sleep(500);
|
|
||||||
}
|
|
||||||
timeoutSecs = 0;
|
|
||||||
while (!finalState.equals(app.getState()) &&
|
while (!finalState.equals(app.getState()) &&
|
||||||
timeoutSecs++ < 20) {
|
timeoutSecs++ < 20) {
|
||||||
System.out.println("App State is : " + app.getState() +
|
System.out.println("App State is : " + app.getState() +
|
||||||
|
@ -95,6 +91,7 @@ public class MockRM extends ResourceManager {
|
||||||
req.setApplicationSubmissionContext(sub);
|
req.setApplicationSubmissionContext(sub);
|
||||||
|
|
||||||
client.submitApplication(req);
|
client.submitApplication(req);
|
||||||
|
// make sure app is immediately available after submit
|
||||||
waitForState(appId, RMAppState.ACCEPTED);
|
waitForState(appId, RMAppState.ACCEPTED);
|
||||||
return getRMContext().getRMApps().get(appId);
|
return getRMContext().getRMApps().get(appId);
|
||||||
}
|
}
|
||||||
|
@ -131,7 +128,7 @@ public class MockRM extends ResourceManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ClientRMService createClientRMService() {
|
protected ClientRMService createClientRMService() {
|
||||||
return new ClientRMService(getRMContext(), getResourceScheduler()) {
|
return new ClientRMService(getRMContext(), getResourceScheduler(), rmAppManager) {
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
//override to not start rpc handler
|
//override to not start rpc handler
|
||||||
|
|
Loading…
Reference in New Issue