You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by wf...@apache.org on 2014/01/17 19:54:11 UTC
git commit: Abort the scheduler if an unchecked exception is handled
while transitioning the lifecycle state.
Updated Branches:
refs/heads/master e3e81a1d9 -> b6fbcde05
Abort the scheduler if an unchecked exception is handled while transitioning
the lifecycle state.
Bugs closed: AURORA-51
Reviewed at https://reviews.apache.org/r/17053/
Project: http://git-wip-us.apache.org/repos/asf/incubator-aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-aurora/commit/b6fbcde0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-aurora/tree/b6fbcde0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-aurora/diff/b6fbcde0
Branch: refs/heads/master
Commit: b6fbcde059cbd0ef75db713a9580860b6abce941
Parents: e3e81a1
Author: Bill Farner <wf...@apache.org>
Authored: Fri Jan 17 10:51:28 2014 -0800
Committer: Bill Farner <wf...@apache.org>
Committed: Fri Jan 17 10:51:28 2014 -0800
----------------------------------------------------------------------
.../aurora/scheduler/SchedulerLifecycle.java | 28 +++++++++++-------
.../scheduler/base/SchedulerException.java | 2 ++
.../scheduler/SchedulerLifecycleTest.java | 31 ++++++++++++++++++--
3 files changed, 49 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/b6fbcde0/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java b/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
index 247e940..f8b6623 100644
--- a/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
+++ b/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
@@ -224,13 +224,8 @@ public class SchedulerLifecycle implements EventSubscriber {
final Closure<Transition<State>> prepareStorage = new Closure<Transition<State>>() {
@Override public void execute(Transition<State> transition) {
- try {
- storage.prepare();
- stateMachine.transition(State.STORAGE_PREPARED);
- } catch (RuntimeException e) {
- stateMachine.transition(State.DEAD);
- throw e;
- }
+ storage.prepare();
+ stateMachine.transition(State.STORAGE_PREPARED);
}
};
@@ -365,18 +360,18 @@ public class SchedulerLifecycle implements EventSubscriber {
.initialState(State.IDLE)
.logTransitions()
.addState(
- Closures.filter(NOT_DEAD, prepareStorage),
+ dieOnError(Closures.filter(NOT_DEAD, prepareStorage)),
State.IDLE,
State.PREPARING_STORAGE, State.DEAD)
.addState(
State.PREPARING_STORAGE,
State.STORAGE_PREPARED, State.DEAD)
.addState(
- Closures.filter(NOT_DEAD, handleLeading),
+ dieOnError(Closures.filter(NOT_DEAD, handleLeading)),
State.STORAGE_PREPARED,
State.LEADER_AWAITING_REGISTRATION, State.DEAD)
.addState(
- Closures.filter(NOT_DEAD, handleRegistered),
+ dieOnError(Closures.filter(NOT_DEAD, handleRegistered)),
State.LEADER_AWAITING_REGISTRATION,
State.REGISTERED_LEADER, State.DEAD)
.addState(
@@ -397,6 +392,19 @@ public class SchedulerLifecycle implements EventSubscriber {
this.leadershipListener = new SchedulerCandidateImpl(stateMachine, leaderControl);
}
+ private Closure<Transition<State>> dieOnError(final Closure<Transition<State>> closure) {
+ return new Closure<Transition<State>>() {
+ @Override public void execute(Transition<State> transition) {
+ try {
+ closure.execute(transition);
+ } catch (RuntimeException e) {
+ stateMachine.transition(State.DEAD);
+ throw e;
+ }
+ }
+ };
+ }
+
/**
* Prepares a scheduler to offer itself as a leader candidate. After this call the scheduler will
* host a live log replica and start syncing data from the leader via the log until it gets called
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/b6fbcde0/src/main/java/org/apache/aurora/scheduler/base/SchedulerException.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/base/SchedulerException.java b/src/main/java/org/apache/aurora/scheduler/base/SchedulerException.java
index 2522b51..c9dc25d 100644
--- a/src/main/java/org/apache/aurora/scheduler/base/SchedulerException.java
+++ b/src/main/java/org/apache/aurora/scheduler/base/SchedulerException.java
@@ -17,6 +17,8 @@ package org.apache.aurora.scheduler.base;
/**
* Indicates some form of unexpected scheduler exception.
+ * TOOO(wfarner): This really should be a checked exception, or the semantics of its
+ * use should change.
*/
public class SchedulerException extends RuntimeException {
public SchedulerException(String message) {
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/b6fbcde0/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java b/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java
index da7a167..ce9b393 100644
--- a/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/SchedulerLifecycleTest.java
@@ -30,6 +30,7 @@ import org.apache.aurora.scheduler.events.EventSink;
import org.apache.aurora.scheduler.events.PubsubEvent.DriverRegistered;
import org.apache.aurora.scheduler.events.PubsubEvent.SchedulerActive;
import org.apache.aurora.scheduler.storage.Storage.MutateWork.NoResult.Quiet;
+import org.apache.aurora.scheduler.storage.Storage.StorageException;
import org.apache.aurora.scheduler.storage.testing.StorageTestUtil;
import org.apache.mesos.Protos.Status;
import org.apache.mesos.SchedulerDriver;
@@ -40,6 +41,7 @@ import org.junit.Test;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
import static org.junit.Assert.fail;
public class SchedulerLifecycleTest extends EasyMockTest {
@@ -85,7 +87,7 @@ public class SchedulerLifecycleTest extends EasyMockTest {
}
@Test
- public void testAutoFailover() throws Throwable {
+ public void testAutoFailover() throws Exception {
// Test that when timed failover is initiated, cleanup is done in a way that should allow the
// application to tear down cleanly. Specifically, neglecting to call leaderControl.leave()
// can result in a lame duck scheduler process.
@@ -121,7 +123,7 @@ public class SchedulerLifecycleTest extends EasyMockTest {
}
@Test
- public void testDefeatedBeforeRegistered() throws Throwable {
+ public void testDefeatedBeforeRegistered() throws Exception {
storageUtil.storage.prepare();
storageUtil.storage.start(EasyMock.<Quiet>anyObject());
storageUtil.expectOperations();
@@ -144,4 +146,29 @@ public class SchedulerLifecycleTest extends EasyMockTest {
leaderListener.onLeading(leaderControl);
leaderListener.onDefeated(null);
}
+
+ @Test
+ public void testStorageStartFails() throws Exception {
+ storageUtil.storage.prepare();
+
+ storageUtil.expectOperations();
+ storageUtil.storage.start(EasyMock.<Quiet>anyObject());
+ expectLastCall().andThrow(new StorageException("Recovery failed."));
+
+ leaderControl.leave();
+ driver.stop();
+ storageUtil.storage.stop();
+ shutdownRegistry.execute();
+
+ control.replay();
+
+ LeadershipListener leaderListener = schedulerLifecycle.prepare();
+
+ try {
+ leaderListener.onLeading(leaderControl);
+ fail();
+ } catch (StorageException e) {
+ // Expected.
+ }
+ }
}