You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@twill.apache.org by ch...@apache.org on 2015/05/06 05:55:26 UTC
[2/4] incubator-twill git commit: (TWILL-69) Removed guava
dependencies from twill-api and twill-common modules
(TWILL-69) Removed guava dependencies from twill-api and twill-common modules
Following changes are backward incompatible:
- TwillController no longer extends from Guava Service
- No more start() method. stopAndWait() becomes terminate()
- TwillRunnerService no longer extends from Guava Service
- Only has the blocking start() and stop() for start and stop.
- Classes moved from twill-common to twill-core, hence no long public
- o.a.t.common.Services
- o.a.t.common.ServiceListenerAdapter
- o.a.t.common.CompositeService
- o.a.t.common.DefaultResourceReport
Modified all unit-tests and examples to use the new API
Project: http://git-wip-us.apache.org/repos/asf/incubator-twill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-twill/commit/0d217b6d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-twill/tree/0d217b6d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-twill/diff/0d217b6d
Branch: refs/heads/feature/TWILL-69
Commit: 0d217b6d499a901c2a62a5856a042130378be8ca
Parents: ae24a04
Author: Terence Yim <ch...@apache.org>
Authored: Mon May 4 19:23:37 2015 -0700
Committer: Terence Yim <ch...@apache.org>
Committed: Tue May 5 13:48:33 2015 -0700
----------------------------------------------------------------------
pom.xml | 2 +
twill-api/pom.xml | 4 -
.../apache/twill/api/AbstractTwillRunnable.java | 8 +-
.../main/java/org/apache/twill/api/Command.java | 52 ++++---
.../java/org/apache/twill/api/EventHandler.java | 8 +-
.../main/java/org/apache/twill/api/Hosts.java | 15 +-
.../main/java/org/apache/twill/api/Racks.java | 16 +-
.../org/apache/twill/api/ServiceController.java | 67 +++++---
.../org/apache/twill/api/TwillController.java | 7 +-
.../twill/api/TwillRunnableSpecification.java | 6 +-
.../apache/twill/api/TwillRunnerService.java | 20 ++-
.../apache/twill/api/TwillSpecification.java | 79 +++++-----
.../apache/twill/api/logging/LogHandler.java | 5 +-
.../twill/api/logging/PrinterLogHandler.java | 8 +-
.../DefaultEventHandlerSpecification.java | 5 +-
.../twill/internal/DefaultResourceReport.java | 151 -------------------
.../internal/DefaultRuntimeSpecification.java | 5 +-
.../DefaultTwillRunnableSpecification.java | 7 +-
.../internal/DefaultTwillSpecification.java | 46 +++---
.../java/org/apache/twill/internal/RunIds.java | 5 +-
twill-common/pom.xml | 4 -
.../apache/twill/common/CompositeService.java | 109 -------------
.../twill/common/ServiceListenerAdapter.java | 50 ------
.../java/org/apache/twill/common/Services.java | 140 -----------------
.../java/org/apache/twill/common/Threads.java | 32 ++--
.../apache/twill/filesystem/LocalLocation.java | 16 +-
.../twill/filesystem/LocationFactories.java | 6 +-
.../twill/common/CompositeServiceTest.java | 145 ------------------
.../org/apache/twill/common/ServicesTest.java | 106 -------------
.../AbstractExecutionServiceController.java | 68 ++++++++-
.../apache/twill/internal/CompositeService.java | 109 +++++++++++++
.../twill/internal/DefaultResourceReport.java | 151 +++++++++++++++++++
.../twill/internal/ServiceListenerAdapter.java | 50 ++++++
.../org/apache/twill/internal/Services.java | 141 +++++++++++++++++
.../internal/TwillContainerController.java | 3 +-
.../twill/internal/logging/KafkaAppender.java | 2 +-
.../twill/internal/CompositeServiceTest.java | 145 ++++++++++++++++++
.../apache/twill/internal/ControllerTest.java | 35 ++---
.../org/apache/twill/internal/ServicesTest.java | 106 +++++++++++++
.../apache/twill/kafka/client/KafkaTest.java | 2 +-
.../twill/discovery/ZKDiscoveryServiceTest.java | 5 +-
.../twill/example/yarn/BundledJarExample.java | 15 +-
.../apache/twill/example/yarn/HelloWorld.java | 15 +-
.../java/org/apache/twill/test/Java8Test.java | 5 +-
.../org/apache/twill/internal/ServiceMain.java | 4 -
.../internal/appmaster/RunningContainers.java | 6 +-
.../twill/yarn/YarnTwillRunnerService.java | 58 ++++---
.../org/apache/twill/yarn/BaseYarnTest.java | 2 +-
.../apache/twill/yarn/ContainerSizeTestRun.java | 7 +-
.../org/apache/twill/yarn/DebugTestRun.java | 17 +--
.../twill/yarn/DistributeShellTestRun.java | 12 +-
.../apache/twill/yarn/EchoServerTestRun.java | 11 +-
.../twill/yarn/FailureRestartTestRun.java | 3 +-
.../twill/yarn/InitializeFailTestRun.java | 3 +-
.../org/apache/twill/yarn/LocalFileTestRun.java | 2 +-
.../apache/twill/yarn/LogHandlerTestRun.java | 5 +-
.../twill/yarn/PlacementPolicyTestRun.java | 17 ++-
.../twill/yarn/ProvisionTimeoutTestRun.java | 3 +-
.../twill/yarn/ResourceReportTestRun.java | 19 ++-
.../twill/yarn/ServiceDiscoveryTestRun.java | 11 +-
.../apache/twill/yarn/SessionExpireTestRun.java | 15 +-
.../org/apache/twill/yarn/SocketServer.java | 6 -
.../apache/twill/yarn/TaskCompletedTestRun.java | 20 +--
.../org/apache/twill/yarn/YarnTestUtils.java | 20 +--
64 files changed, 1158 insertions(+), 1059 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9f923c3..e079273 100644
--- a/pom.xml
+++ b/pom.xml
@@ -278,6 +278,7 @@
<exclude>**/README</exclude>
<exclude>src/test/resources/header.txt</exclude>
<exclude>**/zookeeper.out</exclude>
+ <exclude>twill-java8-test/target/**</exclude>
</excludes>
</configuration>
<executions>
@@ -748,6 +749,7 @@
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>${findbugs.jsr305.version}</version>
+ <optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/pom.xml
----------------------------------------------------------------------
diff --git a/twill-api/pom.xml b/twill-api/pom.xml
index 1354d7a..f36444e 100644
--- a/twill-api/pom.xml
+++ b/twill-api/pom.xml
@@ -43,10 +43,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/AbstractTwillRunnable.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/AbstractTwillRunnable.java b/twill-api/src/main/java/org/apache/twill/api/AbstractTwillRunnable.java
index 614099d..a17c578 100644
--- a/twill-api/src/main/java/org/apache/twill/api/AbstractTwillRunnable.java
+++ b/twill-api/src/main/java/org/apache/twill/api/AbstractTwillRunnable.java
@@ -17,8 +17,8 @@
*/
package org.apache.twill.api;
-import com.google.common.collect.ImmutableMap;
-
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -30,11 +30,11 @@ public abstract class AbstractTwillRunnable implements TwillRunnable {
private TwillContext context;
protected AbstractTwillRunnable() {
- this.args = ImmutableMap.of();
+ this(Collections.<String, String>emptyMap());
}
protected AbstractTwillRunnable(Map<String, String> args) {
- this.args = ImmutableMap.copyOf(args);
+ this.args = Collections.unmodifiableMap(new HashMap<String, String>(args));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/Command.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/Command.java b/twill-api/src/main/java/org/apache/twill/api/Command.java
index b23b3a8..5200aeb 100644
--- a/twill-api/src/main/java/org/apache/twill/api/Command.java
+++ b/twill-api/src/main/java/org/apache/twill/api/Command.java
@@ -17,10 +17,8 @@
*/
package org.apache.twill.api;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -35,13 +33,15 @@ public interface Command {
/**
* Builder for creating {@link Command} object.
*/
- static final class Builder {
+ final class Builder {
private final String command;
- private final ImmutableMap.Builder<String, String> options = ImmutableMap.builder();
+ private final Map<String, String> options = new HashMap<String, String>();
public static Builder of(String command) {
- Preconditions.checkArgument(command != null, "Command cannot be null.");
+ if (command == null) {
+ throw new IllegalArgumentException("Command cannot be null.");
+ }
return new Builder(command);
}
@@ -56,7 +56,7 @@ public interface Command {
}
public Command build() {
- return new SimpleCommand(command, options.build());
+ return new SimpleCommand(command, Collections.unmodifiableMap(new HashMap<String, String>(options)));
}
private Builder(String command) {
@@ -86,28 +86,32 @@ public interface Command {
}
@Override
- public int hashCode() {
- return Objects.hashCode(command, options);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ SimpleCommand that = (SimpleCommand) o;
+ return command.equals(that.command) && options.equals(that.options);
+
}
@Override
- public String toString() {
- return Objects.toStringHelper(Command.class)
- .add("command", command)
- .add("options", options)
- .toString();
+ public int hashCode() {
+ int result = command.hashCode();
+ result = 31 * result + options.hashCode();
+ return result;
}
@Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof Command)) {
- return false;
- }
- Command other = (Command) obj;
- return command.equals(other.getCommand()) && options.equals(other.getOptions());
+ public String toString() {
+ return "SimpleCommand{" +
+ "command='" + command + '\'' +
+ ", options=" + options +
+ '}';
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/EventHandler.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/EventHandler.java b/twill-api/src/main/java/org/apache/twill/api/EventHandler.java
index ede5b65..a19c0b3 100644
--- a/twill-api/src/main/java/org/apache/twill/api/EventHandler.java
+++ b/twill-api/src/main/java/org/apache/twill/api/EventHandler.java
@@ -17,8 +17,7 @@
*/
package org.apache.twill.api;
-import com.google.common.collect.ImmutableMap;
-
+import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -117,7 +116,8 @@ public abstract class EventHandler {
/**
* Invoked by the application to initialize this EventHandler instance.
- * @param context
+ *
+ * @param context context object for accessing the event handler execution context.
*/
public void initialize(EventHandlerContext context) {
this.context = context;
@@ -141,6 +141,6 @@ public abstract class EventHandler {
* Returns set of configurations available at runtime for access.
*/
protected Map<String, String> getConfigs() {
- return ImmutableMap.of();
+ return Collections.emptyMap();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/Hosts.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/Hosts.java b/twill-api/src/main/java/org/apache/twill/api/Hosts.java
index 90a27ad..89e4df4 100644
--- a/twill-api/src/main/java/org/apache/twill/api/Hosts.java
+++ b/twill-api/src/main/java/org/apache/twill/api/Hosts.java
@@ -17,9 +17,9 @@
*/
package org.apache.twill.api;
-import com.google.common.collect.ImmutableSet;
-
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -30,14 +30,15 @@ public class Hosts {
private final Set<String> hosts;
public Hosts(Set<String> hosts) {
- this.hosts = ImmutableSet.copyOf(hosts);
+ this.hosts = Collections.unmodifiableSet(new HashSet<String>(hosts));
}
public Hosts(String host, String...moreHosts) {
- this.hosts = ImmutableSet.<String>builder()
- .add(host)
- .addAll(Arrays.asList(moreHosts))
- .build();
+ Set<String> hosts = new HashSet<String>();
+ hosts.add(host);
+ hosts.addAll(Arrays.asList(moreHosts));
+
+ this.hosts = Collections.unmodifiableSet(hosts);
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/Racks.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/Racks.java b/twill-api/src/main/java/org/apache/twill/api/Racks.java
index 04eedd0..1235293 100644
--- a/twill-api/src/main/java/org/apache/twill/api/Racks.java
+++ b/twill-api/src/main/java/org/apache/twill/api/Racks.java
@@ -17,9 +17,9 @@
*/
package org.apache.twill.api;
-import com.google.common.collect.ImmutableSet;
-
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -30,14 +30,16 @@ public class Racks {
private final Set<String> racks;
public Racks(Set<String> racks) {
- this.racks = ImmutableSet.copyOf(racks);
+ this.racks = Collections.unmodifiableSet(new HashSet<String>(racks));
}
public Racks(String rack, String...moreRacks) {
- this.racks = ImmutableSet.<String>builder()
- .add(rack)
- .addAll(Arrays.asList(moreRacks))
- .build();
+ Set<String> racks = new HashSet<String>();
+ racks.add(rack);
+ racks.addAll(Arrays.asList(moreRacks));
+
+ this.racks = Collections.unmodifiableSet(racks);
+
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/ServiceController.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/ServiceController.java b/twill-api/src/main/java/org/apache/twill/api/ServiceController.java
index 0ea64f9..1ea86b2 100644
--- a/twill-api/src/main/java/org/apache/twill/api/ServiceController.java
+++ b/twill-api/src/main/java/org/apache/twill/api/ServiceController.java
@@ -17,15 +17,16 @@
*/
package org.apache.twill.api;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.Service;
-
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* This interface is for controlling a remote running service.
*/
-public interface ServiceController extends Service {
+public interface ServiceController {
/**
* Returns the {@link RunId} of the running application.
@@ -35,19 +36,30 @@ public interface ServiceController extends Service {
/**
* Sends a user command to the running application.
* @param command The command to send.
- * @return A {@link ListenableFuture} that will be completed when the command is successfully processed
+ * @return A {@link Future} that will be completed when the command is successfully processed
* by the target application.
*/
- ListenableFuture<Command> sendCommand(Command command);
+ Future<Command> sendCommand(Command command);
/**
* Sends a user command to the given runnable of the running application.
* @param runnableName Name of the {@link TwillRunnable}.
* @param command The command to send.
- * @return A {@link ListenableFuture} that will be completed when the command is successfully processed
+ * @return A {@link Future} that will be completed when the command is successfully processed
* by the target runnable.
*/
- ListenableFuture<Command> sendCommand(String runnableName, Command command);
+ Future<Command> sendCommand(String runnableName, Command command);
+
+ /**
+ * Requests to terminate the running service. The service will be given chance to shutdown gracefully.
+ * This method returns immediately and caller can get the termination state through the future returned.
+ * Calling this method multiple times is allowed and a {@link Future} representing the termination state
+ * will be returned.
+ *
+ * @return a {@link Future} that represents the termination of the service. The future result will be
+ * this {@link ServiceController}. If the service terminated due to exception, the future will carry the exception.
+ */
+ Future<? extends ServiceController> terminate();
/**
* Requests to forcefully kill a running service.
@@ -55,16 +67,35 @@ public interface ServiceController extends Service {
void kill();
/**
- * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given
- * executor. The listener will have the corresponding transition method called whenever the
- * service changes state. When added, the current state of the service will be reflected through
- * callback to the listener. Methods on the listener is guaranteed to be called no more than once.
+ * Attaches a {@link Runnable} that will get executed when the service is running.
+ *
+ * @param runnable the {@link Runnable} to be executed when the service is running.
+ * @param executor the executor in which the runnable will be executed with.
+ */
+ void onRunning(Runnable runnable, Executor executor);
+
+ /**
+ * Attaches a {@link Runnable} that will get executed when the serivce is terminated.
+ *
+ * @param runnable the {@link Runnable} to be executed when the service is terminated.
+ * @param executor the executor in which the runnable will be executed with.
+ */
+ void onTerminated(Runnable runnable, Executor executor);
+
+ /**
+ * Waits for termination of the remote service.
+ *
+ * @throws ExecutionException if the service terminated due to exception.
+ */
+ void awaitTerminated() throws ExecutionException;
+
+ /**
+ * Waits for termination of the remote service for no more than the given timeout limit.
*
- * @param listener the listener to run when the service changes state is complete
- * @param executor the executor in which the the listeners callback methods will be run. For fast,
- * lightweight listeners that would be safe to execute in any thread, consider
- * {@link com.google.common.util.concurrent.MoreExecutors#sameThreadExecutor}.
+ * @param timeout the maximum time to wait
+ * @param timeoutUnit the time unit of the timeout
+ * @throws TimeoutException if the service is not terminated within the given time.
+ * @throws ExecutionException if the service terminated due to exception.
*/
- @Override
- void addListener(Listener listener, Executor executor);
+ void awaitTerminated(long timeout, TimeUnit timeoutUnit) throws TimeoutException, ExecutionException;
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/TwillController.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/TwillController.java b/twill-api/src/main/java/org/apache/twill/api/TwillController.java
index 7c5089d..65b9b2d 100644
--- a/twill-api/src/main/java/org/apache/twill/api/TwillController.java
+++ b/twill-api/src/main/java/org/apache/twill/api/TwillController.java
@@ -17,11 +17,12 @@
*/
package org.apache.twill.api;
-import com.google.common.util.concurrent.ListenableFuture;
import org.apache.twill.api.logging.LogHandler;
import org.apache.twill.discovery.Discoverable;
import org.apache.twill.discovery.ServiceDiscovered;
+import java.util.concurrent.Future;
+
/**
* For controlling a running application.
*/
@@ -46,11 +47,11 @@ public interface TwillController extends ServiceController {
*
* @param runnable The name of the runnable.
* @param newCount Number of instances for the given runnable.
- * @return A {@link ListenableFuture} that will be completed when the number running instances has been
+ * @return A {@link Future} that will be completed when the number running instances has been
* successfully changed. The future will carry the new count as the result. If there is any error
* while changing instances, it'll be reflected in the future.
*/
- ListenableFuture<Integer> changeInstances(String runnable, int newCount);
+ Future<Integer> changeInstances(String runnable, int newCount);
/**
* Get a snapshot of the resources used by the application, broken down by each runnable.
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/TwillRunnableSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/TwillRunnableSpecification.java b/twill-api/src/main/java/org/apache/twill/api/TwillRunnableSpecification.java
index d161f9d..fe85d0b 100644
--- a/twill-api/src/main/java/org/apache/twill/api/TwillRunnableSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/api/TwillRunnableSpecification.java
@@ -17,9 +17,9 @@
*/
package org.apache.twill.api;
-import com.google.common.collect.ImmutableMap;
import org.apache.twill.internal.DefaultTwillRunnableSpecification;
+import java.util.Collections;
import java.util.Map;
/**
@@ -36,7 +36,7 @@ public interface TwillRunnableSpecification {
/**
* Builder for constructing {@link TwillRunnableSpecification}.
*/
- static final class Builder {
+ final class Builder {
private String name;
private Map<String, String> args;
@@ -59,7 +59,7 @@ public interface TwillRunnableSpecification {
}
public AfterConfigs noConfigs() {
- Builder.this.args = ImmutableMap.of();
+ Builder.this.args = Collections.emptyMap();
return new AfterConfigs();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/TwillRunnerService.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/TwillRunnerService.java b/twill-api/src/main/java/org/apache/twill/api/TwillRunnerService.java
index 76ec136..77d2c42 100644
--- a/twill-api/src/main/java/org/apache/twill/api/TwillRunnerService.java
+++ b/twill-api/src/main/java/org/apache/twill/api/TwillRunnerService.java
@@ -17,13 +17,25 @@
*/
package org.apache.twill.api;
-import com.google.common.util.concurrent.Service;
-
/**
- * A {@link TwillRunner} that extends {@link Service} to provide lifecycle management functions.
+ * A {@link TwillRunner} that provides lifecycle management functions.
* The {@link #start()} method needs to be called before calling any other method of this interface.
* When done with this service, call {@link #stop()} to release any resources that it holds.
*/
-public interface TwillRunnerService extends TwillRunner, Service {
+public interface TwillRunnerService extends TwillRunner {
+
+ /**
+ * Starts the service. Calling this method on a already started instance has no effect.
+ * A service that is stopped cannot be started again.
+ *
+ * @throws RuntimeException if the service failed to start.
+ */
+ void start();
+ /**
+ * Stops the service. Calling this method on a already stopped instance has no effect.
+ *
+ * @throws RuntimeException if the service failed to start.
+ */
+ void stop();
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/TwillSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/TwillSpecification.java b/twill-api/src/main/java/org/apache/twill/api/TwillSpecification.java
index ed37190..a689529 100644
--- a/twill-api/src/main/java/org/apache/twill/api/TwillSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/api/TwillSpecification.java
@@ -17,12 +17,6 @@
*/
package org.apache.twill.api;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import org.apache.twill.internal.DefaultLocalFile;
import org.apache.twill.internal.DefaultRuntimeSpecification;
import org.apache.twill.internal.DefaultTwillRunnableSpecification;
@@ -30,7 +24,11 @@ import org.apache.twill.internal.DefaultTwillSpecification;
import java.io.File;
import java.net.URI;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -129,12 +127,12 @@ public interface TwillSpecification {
/**
* Builder for constructing instance of {@link TwillSpecification}.
*/
- static final class Builder {
+ final class Builder {
private String name;
- private Map<String, RuntimeSpecification> runnables = Maps.newHashMap();
- private List<Order> orders = Lists.newArrayList();
- private List<PlacementPolicy> placementPolicies = Lists.newArrayList();
+ private Map<String, RuntimeSpecification> runnables = new HashMap<String, RuntimeSpecification>();
+ private List<Order> orders = new ArrayList<Order>();
+ private List<PlacementPolicy> placementPolicies = new ArrayList<PlacementPolicy>();
private EventHandlerSpecification eventHandler;
public static NameSetter with() {
@@ -200,9 +198,9 @@ public interface TwillSpecification {
final ResourceSpecification resourceSpec) {
final TwillRunnableSpecification spec = new DefaultTwillRunnableSpecification(
runnable.getClass().getName(), name, runnable.configure().getConfigs());
- return new RuntimeSpecificationAdder(new Function<Collection<LocalFile>, RunnableSetter>() {
+ return new RuntimeSpecificationAdder(new LocalFileCompleter() {
@Override
- public RunnableSetter apply(Collection<LocalFile> files) {
+ public RunnableSetter complete(Collection<LocalFile> files) {
runnables.put(spec.getName(), new DefaultRuntimeSpecification(spec.getName(), spec, resourceSpec, files));
return RunnableSetter.this;
}
@@ -226,13 +224,20 @@ public interface TwillSpecification {
}
/**
+ * Internal interface for completing addition of {@link LocalFile} to a runnable.
+ */
+ private interface LocalFileCompleter {
+ RunnableSetter complete(Collection<LocalFile> files);
+ }
+
+ /**
* For setting runtime specific settings.
*/
public final class RuntimeSpecificationAdder {
- private final Function<Collection<LocalFile>, RunnableSetter> completer;
+ private final LocalFileCompleter completer;
- RuntimeSpecificationAdder(Function<Collection<LocalFile>, RunnableSetter> completer) {
+ RuntimeSpecificationAdder(LocalFileCompleter completer) {
this.completer = completer;
}
@@ -241,7 +246,7 @@ public interface TwillSpecification {
}
public RunnableSetter noLocalFiles() {
- return completer.apply(ImmutableList.<LocalFile>of());
+ return completer.complete(Collections.<LocalFile>emptyList());
}
}
@@ -261,10 +266,10 @@ public interface TwillSpecification {
public final class MoreFile implements LocalFileAdder {
- private final Function<Collection<LocalFile>, RunnableSetter> completer;
- private final List<LocalFile> files = Lists.newArrayList();
+ private final LocalFileCompleter completer;
+ private final List<LocalFile> files = new ArrayList<LocalFile>();
- public MoreFile(Function<Collection<LocalFile>, RunnableSetter> completer) {
+ public MoreFile(LocalFileCompleter completer) {
this.completer = completer;
}
@@ -301,7 +306,7 @@ public interface TwillSpecification {
}
public RunnableSetter apply() {
- return completer.apply(files);
+ return completer.complete(files);
}
}
@@ -387,16 +392,16 @@ public interface TwillSpecification {
private PlacementPolicySetter addPlacementPolicy(PlacementPolicy.Type type, Hosts hosts, Racks racks,
String runnableName, String...runnableNames) {
- Preconditions.checkArgument(runnableName != null, "Name cannot be null.");
- Preconditions.checkArgument(runnables.containsKey(runnableName), "Runnable not exists.");
- Preconditions.checkArgument(!contains(runnableName),
- "Runnable (" + runnableName + ") cannot belong to more than one Placement Policy");
- Set<String> runnableNamesSet = Sets.newHashSet(runnableName);
+ checkArgument(runnableName != null, "Name cannot be null.");
+ checkArgument(runnables.containsKey(runnableName), "Runnable not exists.");
+ checkArgument(!contains(runnableName),
+ "Runnable (" + runnableName + ") cannot belong to more than one Placement Policy");
+ Set<String> runnableNamesSet = new HashSet<String>(Collections.singleton(runnableName));
for (String name : runnableNames) {
- Preconditions.checkArgument(name != null, "Name cannot be null.");
- Preconditions.checkArgument(runnables.containsKey(name), "Runnable not exists.");
- Preconditions.checkArgument(!contains(name),
- "Runnable (" + name + ") cannot belong to more than one Placement Policy");
+ checkArgument(name != null, "Name cannot be null.");
+ checkArgument(runnables.containsKey(name), "Runnable not exists.");
+ checkArgument(!contains(name),
+ "Runnable (" + name + ") cannot belong to more than one Placement Policy");
runnableNamesSet.add(name);
}
placementPolicies.add(
@@ -468,7 +473,7 @@ public interface TwillSpecification {
@Override
public TwillSpecification build() {
// Set to track with runnable hasn't been assigned an order.
- Set<String> runnableNames = Sets.newHashSet(runnables.keySet());
+ Set<String> runnableNames = new HashSet<String>(runnables.keySet());
for (Order order : orders) {
runnableNames.removeAll(order.getNames());
}
@@ -479,13 +484,13 @@ public interface TwillSpecification {
}
private void addOrder(final Order.Type type, String name, String...names) {
- Preconditions.checkArgument(name != null, "Name cannot be null.");
- Preconditions.checkArgument(runnables.containsKey(name), "Runnable not exists.");
+ checkArgument(name != null, "Name cannot be null.");
+ checkArgument(runnables.containsKey(name), "Runnable not exists.");
- Set<String> runnableNames = Sets.newHashSet(name);
+ Set<String> runnableNames = new HashSet<String>(Collections.singleton(name));
for (String runnableName : names) {
- Preconditions.checkArgument(name != null, "Name cannot be null.");
- Preconditions.checkArgument(runnables.containsKey(name), "Runnable not exists.");
+ checkArgument(name != null, "Name cannot be null.");
+ checkArgument(runnables.containsKey(name), "Runnable not exists.");
runnableNames.add(runnableName);
}
@@ -493,6 +498,12 @@ public interface TwillSpecification {
}
}
+ private void checkArgument(boolean condition, String msgFormat, Object...args) {
+ if (!condition) {
+ throw new IllegalArgumentException(String.format(msgFormat, args));
+ }
+ }
+
private Builder() {}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/logging/LogHandler.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/logging/LogHandler.java b/twill-api/src/main/java/org/apache/twill/api/logging/LogHandler.java
index afded19..70cb25d 100644
--- a/twill-api/src/main/java/org/apache/twill/api/logging/LogHandler.java
+++ b/twill-api/src/main/java/org/apache/twill/api/logging/LogHandler.java
@@ -18,9 +18,12 @@
package org.apache.twill.api.logging;
/**
- *
+ * Represents class that can receive logs from the application.
*/
public interface LogHandler {
+ /**
+ * Invokes when there is new {@link LogEntry} received from the application.
+ */
void onLog(LogEntry logEntry);
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/api/logging/PrinterLogHandler.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/api/logging/PrinterLogHandler.java b/twill-api/src/main/java/org/apache/twill/api/logging/PrinterLogHandler.java
index c6d6501..ef3c828 100644
--- a/twill-api/src/main/java/org/apache/twill/api/logging/PrinterLogHandler.java
+++ b/twill-api/src/main/java/org/apache/twill/api/logging/PrinterLogHandler.java
@@ -17,20 +17,22 @@
*/
package org.apache.twill.api.logging;
-import com.google.common.base.Splitter;
-
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Formatter;
import java.util.TimeZone;
+import java.util.regex.Pattern;
/**
* A {@link LogHandler} that prints the {@link LogEntry} through a {@link PrintWriter}.
*/
public final class PrinterLogHandler implements LogHandler {
+ // A regex for splitting string by ".".
+ private static final Pattern DOT_SPLIT = Pattern.compile("\\.");
+
private static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
@@ -99,7 +101,7 @@ public final class PrinterLogHandler implements LogHandler {
private String getShortenLoggerName(String loggerName) {
StringBuilder builder = new StringBuilder();
String previous = null;
- for (String part : Splitter.on('.').split(loggerName)) {
+ for (String part : DOT_SPLIT.split(loggerName)) {
if (previous != null) {
builder.append(previous.charAt(0)).append('.');
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/DefaultEventHandlerSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/DefaultEventHandlerSpecification.java b/twill-api/src/main/java/org/apache/twill/internal/DefaultEventHandlerSpecification.java
index 83e7c38..e848315 100644
--- a/twill-api/src/main/java/org/apache/twill/internal/DefaultEventHandlerSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/internal/DefaultEventHandlerSpecification.java
@@ -17,10 +17,11 @@
*/
package org.apache.twill.internal;
-import com.google.common.collect.ImmutableMap;
import org.apache.twill.api.EventHandler;
import org.apache.twill.api.EventHandlerSpecification;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -39,7 +40,7 @@ public class DefaultEventHandlerSpecification implements EventHandlerSpecificati
public DefaultEventHandlerSpecification(EventHandler eventHandler) {
EventHandlerSpecification spec = eventHandler.configure();
this.className = eventHandler.getClass().getName();
- this.configs = ImmutableMap.copyOf(spec.getConfigs());
+ this.configs = Collections.unmodifiableMap(new HashMap<String, String>(spec.getConfigs()));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/DefaultResourceReport.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/DefaultResourceReport.java b/twill-api/src/main/java/org/apache/twill/internal/DefaultResourceReport.java
deleted file mode 100644
index 767ee45..0000000
--- a/twill-api/src/main/java/org/apache/twill/internal/DefaultResourceReport.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.internal;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import org.apache.twill.api.ResourceReport;
-import org.apache.twill.api.TwillRunResources;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Implementation of {@link org.apache.twill.api.ResourceReport} with some
- * additional methods for maintaining the report.
- */
-public final class DefaultResourceReport implements ResourceReport {
- private final SetMultimap<String, TwillRunResources> usedResources;
- private final TwillRunResources appMasterResources;
- private final String applicationId;
- private final AtomicReference<List<String>> services;
-
- public DefaultResourceReport(String applicationId, TwillRunResources masterResources) {
- this(applicationId, masterResources, ImmutableMap.<String, Collection<TwillRunResources>>of());
- }
-
- public DefaultResourceReport(String applicationId, TwillRunResources masterResources,
- Map<String, Collection<TwillRunResources>> resources) {
- this(applicationId, masterResources, resources, ImmutableList.<String>of());
- }
-
- public DefaultResourceReport(String applicationId, TwillRunResources masterResources,
- Map<String, Collection<TwillRunResources>> resources, List<String> services) {
- this.applicationId = applicationId;
- this.appMasterResources = masterResources;
- this.usedResources = HashMultimap.create();
- for (Map.Entry<String, Collection<TwillRunResources>> entry : resources.entrySet()) {
- this.usedResources.putAll(entry.getKey(), entry.getValue());
- }
- this.services = new AtomicReference<List<String>>(services);
- }
-
- /**
- * Add resources used by an instance of the runnable.
- *
- * @param runnableName name of runnable.
- * @param resources resources to add.
- */
- public void addRunResources(String runnableName, TwillRunResources resources) {
- usedResources.put(runnableName, resources);
- }
-
- /**
- * Remove the resource corresponding to the given runnable and container.
- *
- * @param runnableName name of runnable.
- * @param containerId container id of the runnable.
- */
- public void removeRunnableResources(String runnableName, String containerId) {
- TwillRunResources toRemove = null;
- // could be faster if usedResources was a Table, but that makes returning the
- // report a little more complex, and this does not need to be terribly fast.
- for (TwillRunResources resources : usedResources.get(runnableName)) {
- if (resources.getContainerId().equals(containerId)) {
- toRemove = resources;
- break;
- }
- }
- usedResources.remove(runnableName, toRemove);
- }
-
- /**
- * Get all the run resources being used by all instances of the specified runnable.
- *
- * @param runnableName the runnable name.
- * @return resources being used by all instances of the runnable.
- */
- @Override
- public Collection<TwillRunResources> getRunnableResources(String runnableName) {
- return usedResources.get(runnableName);
- }
-
- /**
- * Get all the run resources being used across all runnables.
- *
- * @return all run resources used by all instances of all runnables.
- */
- @Override
- public Map<String, Collection<TwillRunResources>> getResources() {
- return Multimaps.unmodifiableSetMultimap(usedResources).asMap();
- }
-
- /**
- * Get the resources application master is using.
- *
- * @return resources being used by the application master.
- */
- @Override
- public TwillRunResources getAppMasterResources() {
- return appMasterResources;
- }
-
- /**
- * Get the id of the application master.
- *
- * @return id of the application master.
- */
- @Override
- public String getApplicationId() {
- return applicationId;
- }
-
- /**
- * Set the list of services of the application master.
- *
- * @param services list of services to set.
- */
- public void setServices(List<String> services) {
- this.services.set(ImmutableList.copyOf(services));
- }
-
- /**
- * Get the list of services of the application master.
- *
- * @return list of services of the application master.
- */
- @Override
- public List<String> getServices() {
- return services.get();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/DefaultRuntimeSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/DefaultRuntimeSpecification.java b/twill-api/src/main/java/org/apache/twill/internal/DefaultRuntimeSpecification.java
index 9de81b1..6e7053c 100644
--- a/twill-api/src/main/java/org/apache/twill/internal/DefaultRuntimeSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/internal/DefaultRuntimeSpecification.java
@@ -17,13 +17,14 @@
*/
package org.apache.twill.internal;
-import com.google.common.collect.ImmutableList;
import org.apache.twill.api.LocalFile;
import org.apache.twill.api.ResourceSpecification;
import org.apache.twill.api.RuntimeSpecification;
import org.apache.twill.api.TwillRunnableSpecification;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
/**
* Straightforward implementation of {@link RuntimeSpecification}.
@@ -42,7 +43,7 @@ public final class DefaultRuntimeSpecification implements RuntimeSpecification {
this.name = name;
this.runnableSpec = runnableSpec;
this.resourceSpec = resourceSpec;
- this.localFiles = ImmutableList.copyOf(localFiles);
+ this.localFiles = Collections.unmodifiableList(new ArrayList<LocalFile>(localFiles));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillRunnableSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillRunnableSpecification.java b/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillRunnableSpecification.java
index 0d2eb22..68daef2 100644
--- a/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillRunnableSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillRunnableSpecification.java
@@ -17,9 +17,10 @@
*/
package org.apache.twill.internal;
-import com.google.common.collect.ImmutableMap;
import org.apache.twill.api.TwillRunnableSpecification;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
/**
@@ -34,13 +35,13 @@ public final class DefaultTwillRunnableSpecification implements TwillRunnableSpe
public DefaultTwillRunnableSpecification(String className, String name, Map<String, String> arguments) {
this.className = className;
this.name = name;
- this.arguments = ImmutableMap.copyOf(arguments);
+ this.arguments = Collections.unmodifiableMap(new HashMap<String, String>(arguments));
}
public DefaultTwillRunnableSpecification(String className, TwillRunnableSpecification other) {
this.className = className;
this.name = other.getName();
- this.arguments = ImmutableMap.copyOf(other.getConfigs());
+ this.arguments = Collections.unmodifiableMap(new HashMap<String, String>(other.getConfigs()));
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillSpecification.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillSpecification.java b/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillSpecification.java
index 184afb3..0cb6688 100644
--- a/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillSpecification.java
+++ b/twill-api/src/main/java/org/apache/twill/internal/DefaultTwillSpecification.java
@@ -17,17 +17,16 @@
*/
package org.apache.twill.internal;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import org.apache.twill.api.EventHandlerSpecification;
import org.apache.twill.api.Hosts;
import org.apache.twill.api.Racks;
import org.apache.twill.api.RuntimeSpecification;
import org.apache.twill.api.TwillSpecification;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -48,8 +47,8 @@ public final class DefaultTwillSpecification implements TwillSpecification {
List<Order> orders, List<PlacementPolicy> placementPolicies,
EventHandlerSpecification eventHandler) {
this.name = name;
- this.runnables = ImmutableMap.copyOf(runnables);
- this.orders = ImmutableList.copyOf(orders);
+ this.runnables = Collections.unmodifiableMap(new HashMap<String, RuntimeSpecification>(runnables));
+ this.orders = Collections.unmodifiableList(new ArrayList<Order>(orders));
this.placementPolicies = placementPolicies;
this.eventHandler = eventHandler;
}
@@ -88,8 +87,8 @@ public final class DefaultTwillSpecification implements TwillSpecification {
private final Set<String> names;
private final Type type;
- public DefaultOrder(Iterable<String> names, Type type) {
- this.names = ImmutableSet.copyOf(names);
+ public DefaultOrder(Set<String> names, Type type) {
+ this.names = Collections.unmodifiableSet(new HashSet<String>(names));
this.type = type;
}
@@ -105,10 +104,10 @@ public final class DefaultTwillSpecification implements TwillSpecification {
@Override
public String toString() {
- return Objects.toStringHelper(this)
- .add("names", names)
- .add("type", type)
- .toString();
+ return "DefaultOrder{" +
+ "names=" + names +
+ ", type=" + type +
+ '}';
}
}
@@ -122,17 +121,13 @@ public final class DefaultTwillSpecification implements TwillSpecification {
private final Hosts hosts;
private final Racks racks;
- public DefaultPlacementPolicy(Iterable<String> names, Type type, Hosts hosts, Racks racks) {
- this.names = ImmutableSet.copyOf(names);
+ public DefaultPlacementPolicy(Set<String> names, Type type, Hosts hosts, Racks racks) {
+ this.names = Collections.unmodifiableSet(new HashSet<String>(names));
this.type = type;
this.hosts = hosts;
this.racks = racks;
}
- public DefaultPlacementPolicy(Iterable<String> names, Type type) {
- this(names, type, null, null);
- }
-
/**
* @return Set of {@link org.apache.twill.api.TwillRunnable} names that belongs to this placement policy.
*/
@@ -171,17 +166,14 @@ public final class DefaultTwillSpecification implements TwillSpecification {
return this.racks.get();
}
- /**
- * @return String representation of Placement Policy
- */
@Override
public String toString() {
- return Objects.toStringHelper(this)
- .add("names", names)
- .add("type", type)
- .add("hosts", hosts)
- .add("racks", racks)
- .toString();
+ return "DefaultPlacementPolicy{" +
+ "hosts=" + hosts +
+ ", names=" + names +
+ ", type=" + type +
+ ", racks=" + racks +
+ '}';
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-api/src/main/java/org/apache/twill/internal/RunIds.java
----------------------------------------------------------------------
diff --git a/twill-api/src/main/java/org/apache/twill/internal/RunIds.java b/twill-api/src/main/java/org/apache/twill/internal/RunIds.java
index b7641f3..4d071d1 100644
--- a/twill-api/src/main/java/org/apache/twill/internal/RunIds.java
+++ b/twill-api/src/main/java/org/apache/twill/internal/RunIds.java
@@ -17,7 +17,6 @@
*/
package org.apache.twill.internal;
-import com.google.common.base.Preconditions;
import org.apache.twill.api.RunId;
import java.util.UUID;
@@ -43,7 +42,9 @@ public final class RunIds {
final String id;
private RunIdImpl(String id) {
- Preconditions.checkArgument(id != null, "RunId cannot be null.");
+ if (id == null) {
+ throw new IllegalArgumentException("RunId cannot be null.");
+ }
this.id = id;
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/pom.xml
----------------------------------------------------------------------
diff --git a/twill-common/pom.xml b/twill-common/pom.xml
index bfc6e0c..0d1f338 100644
--- a/twill-common/pom.xml
+++ b/twill-common/pom.xml
@@ -31,10 +31,6 @@
<dependencies>
<dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/common/CompositeService.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/common/CompositeService.java b/twill-common/src/main/java/org/apache/twill/common/CompositeService.java
deleted file mode 100644
index 2817988..0000000
--- a/twill-common/src/main/java/org/apache/twill/common/CompositeService.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.common;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.AbstractIdleService;
-import com.google.common.util.concurrent.Service;
-import com.google.common.util.concurrent.UncheckedExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Iterator;
-
-/**
- * A {@link Service} that starts/stops list of services in order.
- */
-public final class CompositeService extends AbstractIdleService {
-
- private static final Logger LOG = LoggerFactory.getLogger(CompositeService.class);
- private final Deque<Service> services;
-
- public CompositeService(Service...services) {
- this(ImmutableList.copyOf(services));
- }
-
- public CompositeService(Iterable<? extends Service> services) {
- this.services = new ArrayDeque<Service>();
- Iterables.addAll(this.services, services);
- }
-
- @Override
- protected void startUp() throws Exception {
- Throwable failureCause = null;
-
- for (Service service : services) {
- try {
- service.startAndWait();
- } catch (UncheckedExecutionException e) {
- failureCause = e.getCause();
- break;
- }
- }
-
- if (failureCause != null) {
- // Stop all running services and then throw the failure exception
- try {
- stopAll();
- } catch (Throwable t) {
- // Ignore the stop error. Just log.
- LOG.warn("Failed when stopping all services on start failure", t);
- }
-
- Throwables.propagateIfPossible(failureCause, Exception.class);
- throw new RuntimeException(failureCause);
- }
- }
-
- @Override
- protected void shutDown() throws Exception {
- stopAll();
- }
-
- private void stopAll() throws Exception {
- Throwable failureCause = null;
-
- // Stop services in reverse order.
- Iterator<Service> itor = services.descendingIterator();
- while (itor.hasNext()) {
- Service service = itor.next();
- try {
- if (service.isRunning() || service.state() == State.STARTING) {
- service.stopAndWait();
- }
- } catch (UncheckedExecutionException e) {
- // Just catch as we want all services stopped
- if (failureCause == null) {
- failureCause = e.getCause();
- } else {
- // Log for sub-sequence service shutdown error, as only the first failure cause will be thrown.
- LOG.warn("Failed to stop service {}", service, e);
- }
- }
- }
-
- if (failureCause != null) {
- Throwables.propagateIfPossible(failureCause, Exception.class);
- throw new RuntimeException(failureCause);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/common/ServiceListenerAdapter.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/common/ServiceListenerAdapter.java b/twill-common/src/main/java/org/apache/twill/common/ServiceListenerAdapter.java
deleted file mode 100644
index 527ba7d..0000000
--- a/twill-common/src/main/java/org/apache/twill/common/ServiceListenerAdapter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.common;
-
-import com.google.common.util.concurrent.Service;
-
-/**
- * An adapter for implementing {@link Service.Listener} with all method default to no-op.
- */
-public abstract class ServiceListenerAdapter implements Service.Listener {
- @Override
- public void starting() {
- // No-op
- }
-
- @Override
- public void running() {
- // No-op
- }
-
- @Override
- public void stopping(Service.State from) {
- // No-op
- }
-
- @Override
- public void terminated(Service.State from) {
- // No-op
- }
-
- @Override
- public void failed(Service.State from, Throwable failure) {
- // No-op
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/common/Services.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/common/Services.java b/twill-common/src/main/java/org/apache/twill/common/Services.java
deleted file mode 100644
index 7e294f0..0000000
--- a/twill-common/src/main/java/org/apache/twill/common/Services.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.common;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.Service;
-import com.google.common.util.concurrent.SettableFuture;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Utility methods for help dealing with {@link Service}.
- */
-public final class Services {
-
- /**
- * Starts a list of {@link Service} one by one. Starting of next Service is triggered from the callback listener
- * thread of the previous Service.
- *
- * @param firstService First service to start.
- * @param moreServices The rest services to start.
- * @return A {@link ListenableFuture} that will be completed when all services are started, with the
- * result carries the completed {@link ListenableFuture} of each corresponding service in the
- * same order as they are passed to this method.
- */
- public static ListenableFuture<List<ListenableFuture<Service.State>>> chainStart(Service firstService,
- Service...moreServices) {
- return doChain(true, firstService, moreServices);
- }
-
- /**
- * Stops a list of {@link Service} one by one. It behaves the same as
- * {@link #chainStart(com.google.common.util.concurrent.Service, com.google.common.util.concurrent.Service...)}
- * except {@link com.google.common.util.concurrent.Service#stop()} is called instead of start.
- *
- * @param firstService First service to stop.
- * @param moreServices The rest services to stop.
- * @return A {@link ListenableFuture} that will be completed when all services are stopped.
- * @see #chainStart(com.google.common.util.concurrent.Service, com.google.common.util.concurrent.Service...)
- */
- public static ListenableFuture<List<ListenableFuture<Service.State>>> chainStop(Service firstService,
- Service...moreServices) {
- return doChain(false, firstService, moreServices);
- }
-
- /**
- * Returns a {@link ListenableFuture} that will be completed when the given service is stopped. If the service
- * stopped due to error, the failure cause would be reflected in the future.
- *
- * @param service The {@link Service} to block on.
- * @return A {@link ListenableFuture} that will be completed when the service is stopped.
- */
- public static ListenableFuture<Service.State> getCompletionFuture(Service service) {
- final SettableFuture<Service.State> resultFuture = SettableFuture.create();
-
- service.addListener(new ServiceListenerAdapter() {
- @Override
- public void terminated(Service.State from) {
- resultFuture.set(Service.State.TERMINATED);
- }
-
- @Override
- public void failed(Service.State from, Throwable failure) {
- resultFuture.setException(failure);
- }
- }, Threads.SAME_THREAD_EXECUTOR);
-
- Service.State state = service.state();
- if (state == Service.State.TERMINATED) {
- return Futures.immediateFuture(state);
- } else if (state == Service.State.FAILED) {
- return Futures.immediateFailedFuture(new IllegalStateException("Service failed with unknown exception."));
- }
-
- return resultFuture;
- }
-
- /**
- * Performs the actual logic of chain Service start/stop.
- */
- private static ListenableFuture<List<ListenableFuture<Service.State>>> doChain(boolean doStart,
- Service firstService,
- Service...moreServices) {
- SettableFuture<List<ListenableFuture<Service.State>>> resultFuture = SettableFuture.create();
- List<ListenableFuture<Service.State>> result = Lists.newArrayListWithCapacity(moreServices.length + 1);
-
- ListenableFuture<Service.State> future = doStart ? firstService.start() : firstService.stop();
- future.addListener(createChainListener(future, moreServices, new AtomicInteger(0), result, resultFuture, doStart),
- Threads.SAME_THREAD_EXECUTOR);
- return resultFuture;
- }
-
- /**
- * Returns a {@link Runnable} that can be used as a {@link ListenableFuture} listener to trigger
- * further service action or completing the result future. Used by
- * {@link #doChain(boolean, com.google.common.util.concurrent.Service, com.google.common.util.concurrent.Service...)}
- */
- private static Runnable createChainListener(final ListenableFuture<Service.State> future, final Service[] services,
- final AtomicInteger idx,
- final List<ListenableFuture<Service.State>> result,
- final SettableFuture<List<ListenableFuture<Service.State>>> resultFuture,
- final boolean doStart) {
- return new Runnable() {
-
- @Override
- public void run() {
- result.add(future);
- int nextIdx = idx.getAndIncrement();
- if (nextIdx == services.length) {
- resultFuture.set(result);
- return;
- }
- ListenableFuture<Service.State> actionFuture = doStart ? services[nextIdx].start() : services[nextIdx].stop();
- actionFuture.addListener(createChainListener(actionFuture, services, idx, result, resultFuture, doStart),
- Threads.SAME_THREAD_EXECUTOR);
- }
- };
- }
-
- private Services() {
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/common/Threads.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/common/Threads.java b/twill-common/src/main/java/org/apache/twill/common/Threads.java
index e33a677..8a90f7b 100644
--- a/twill-common/src/main/java/org/apache/twill/common/Threads.java
+++ b/twill-common/src/main/java/org/apache/twill/common/Threads.java
@@ -17,11 +17,9 @@
*/
package org.apache.twill.common;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicLong;
/**
*
@@ -31,20 +29,32 @@ public final class Threads {
/**
* A executor that execute task from the submitter thread.
*/
- public static final Executor SAME_THREAD_EXECUTOR = MoreExecutors.sameThreadExecutor();
+ public static final Executor SAME_THREAD_EXECUTOR = new Executor() {
+ @Override
+ public void execute(Runnable command) {
+ command.run();
+ }
+ };
/**
* Handy method to create {@link ThreadFactory} that creates daemon threads with the given name format.
*
- * @param nameFormat Name format for the thread names
+ * @param nameFormat Name format for the thread names. It should be a format string compatible
+ * with the {@link String#format(String, Object...)} that takes a single number as the format
+ * argument.
* @return A {@link ThreadFactory}.
- * @see ThreadFactoryBuilder
*/
- public static ThreadFactory createDaemonThreadFactory(String nameFormat) {
- return new ThreadFactoryBuilder()
- .setDaemon(true)
- .setNameFormat(nameFormat)
- .build();
+ public static ThreadFactory createDaemonThreadFactory(final String nameFormat) {
+ final AtomicLong id = new AtomicLong(0);
+ return new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r);
+ t.setDaemon(true);
+ t.setName(String.format(nameFormat, id.getAndIncrement()));
+ return t;
+ }
+ };
}
private Threads() {
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/filesystem/LocalLocation.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/filesystem/LocalLocation.java b/twill-common/src/main/java/org/apache/twill/filesystem/LocalLocation.java
index 3b01e61..a560694 100644
--- a/twill-common/src/main/java/org/apache/twill/filesystem/LocalLocation.java
+++ b/twill-common/src/main/java/org/apache/twill/filesystem/LocalLocation.java
@@ -17,10 +17,6 @@
*/
package org.apache.twill.filesystem;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -29,8 +25,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
+import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
@@ -157,7 +155,7 @@ final class LocalLocation implements Location {
return delete();
}
- Deque<File> stack = Lists.newLinkedList();
+ Deque<File> stack = new LinkedList<File>();
stack.add(file);
while (!stack.isEmpty()) {
File f = stack.peekLast();
@@ -218,7 +216,7 @@ final class LocalLocation implements Location {
@Override
public List<Location> list() throws IOException {
File[] files = file.listFiles();
- ImmutableList.Builder<Location> result = ImmutableList.builder();
+ List<Location> result = new ArrayList<Location>();
if (files != null) {
for (File file : files) {
result.add(new LocalLocation(locationFactory, file));
@@ -226,7 +224,7 @@ final class LocalLocation implements Location {
} else if (!file.exists()) {
throw new FileNotFoundException("File " + file + " does not exist.");
}
- return result.build();
+ return Collections.unmodifiableList(result);
}
@Override
@@ -243,8 +241,8 @@ final class LocalLocation implements Location {
return false;
}
- LocalLocation other = (LocalLocation) o;
- return Objects.equal(file, other.file);
+ LocalLocation that = (LocalLocation) o;
+ return file.equals(that.file);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/main/java/org/apache/twill/filesystem/LocationFactories.java
----------------------------------------------------------------------
diff --git a/twill-common/src/main/java/org/apache/twill/filesystem/LocationFactories.java b/twill-common/src/main/java/org/apache/twill/filesystem/LocationFactories.java
index 751a632..3b21f5e 100644
--- a/twill-common/src/main/java/org/apache/twill/filesystem/LocationFactories.java
+++ b/twill-common/src/main/java/org/apache/twill/filesystem/LocationFactories.java
@@ -17,8 +17,6 @@
*/
package org.apache.twill.filesystem;
-import com.google.common.base.Throwables;
-
import java.io.IOException;
import java.net.URI;
@@ -38,7 +36,7 @@ public final class LocationFactories {
Location base = getDelegate().create(namespace);
return base.append(path);
} catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
@@ -51,7 +49,7 @@ public final class LocationFactories {
Location base = getDelegate().create(namespace);
return base.append(uri.getPath());
} catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/test/java/org/apache/twill/common/CompositeServiceTest.java
----------------------------------------------------------------------
diff --git a/twill-common/src/test/java/org/apache/twill/common/CompositeServiceTest.java b/twill-common/src/test/java/org/apache/twill/common/CompositeServiceTest.java
deleted file mode 100644
index 1c45892..0000000
--- a/twill-common/src/test/java/org/apache/twill/common/CompositeServiceTest.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.common;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.AbstractIdleService;
-import com.google.common.util.concurrent.Service;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests for {@link CompositeService}.
- */
-public class CompositeServiceTest {
-
- @Test
- public void testOrder() throws InterruptedException, ExecutionException, TimeoutException {
- List<Service> services = Lists.newArrayList();
-
- // Start 10 services and check their start sequence is ordered.
- Semaphore semaphore = new Semaphore(0);
- for (int i = 0; i < 10; i++) {
- services.add(new TestService(semaphore, i));
- }
-
- Service service = new CompositeService(services);
- service.start().get(5, TimeUnit.SECONDS);
-
- // There should be 10 permits after all 10 services started
- Assert.assertTrue(semaphore.tryAcquire(10, 5, TimeUnit.SECONDS));
-
- // Check all services are running
- Assert.assertTrue(Iterables.all(services, serviceStatePredicate(Service.State.RUNNING)));
-
- // Release 10 permits for the stop sequence to start
- semaphore.release(10);
- service.stop().get(5, TimeUnit.SECONDS);
-
- // There should be no permit left after all 10 services stopped
- Assert.assertFalse(semaphore.tryAcquire(10));
-
- // Check all services are stopped
- Assert.assertTrue(Iterables.all(services, serviceStatePredicate(Service.State.TERMINATED)));
- }
-
- @Test
- public void testErrorStart() throws InterruptedException {
- List<Service> services = Lists.newArrayList();
-
- // Create 5 services. The forth one will got a start failure.
- Semaphore semaphore = new Semaphore(0);
- for (int i = 0; i < 5; i++) {
- services.add(new TestService(semaphore, i, i == 3));
- }
-
- Service service = new CompositeService(services);
- try {
- service.start().get();
- Assert.fail();
- } catch (ExecutionException e) {
- // Expected
- }
-
- // Verify all services are not in running state
- Assert.assertTrue(Iterables.all(services, Predicates.not(serviceStatePredicate(Service.State.RUNNING))));
-
- // There should be one service in error state
- Assert.assertTrue(Iterables.removeIf(services, serviceStatePredicate(Service.State.FAILED)));
-
- for (Service s : services) {
- Assert.assertNotEquals(3, ((TestService) s).getOrder());
- }
- }
-
- private Predicate<Service> serviceStatePredicate(final Service.State state) {
- return new Predicate<Service>() {
- @Override
- public boolean apply(Service service) {
- return service.state() == state;
- }
- };
- }
-
- private static final class TestService extends AbstractIdleService {
-
- private final Semaphore semaphore;
- private final int order;
- private final boolean startFail;
-
- private TestService(Semaphore semaphore, int order) {
- this(semaphore, order, false);
- }
-
- private TestService(Semaphore semaphore, int order, boolean startFail) {
- this.semaphore = semaphore;
- this.order = order;
- this.startFail = startFail;
- }
-
- public int getOrder() {
- return order;
- }
-
- @Override
- protected void startUp() throws Exception {
- Preconditions.checkState(!startFail, "Fail to start service of order %s", order);
-
- // Acquire all permits emitted by previous service
- semaphore.acquire(order);
- // Emit enough permits for next service
- semaphore.release(order + 1);
- }
-
- @Override
- protected void shutDown() throws Exception {
- semaphore.acquire(order + 1);
- semaphore.release(order);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-common/src/test/java/org/apache/twill/common/ServicesTest.java
----------------------------------------------------------------------
diff --git a/twill-common/src/test/java/org/apache/twill/common/ServicesTest.java b/twill-common/src/test/java/org/apache/twill/common/ServicesTest.java
deleted file mode 100644
index c0aa7ee..0000000
--- a/twill-common/src/test/java/org/apache/twill/common/ServicesTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.twill.common;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AbstractIdleService;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.Service;
-import org.junit.Assert;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Unit test for {@link Services} methods.
- */
-public class ServicesTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(ServicesTest.class);
-
- @Test
- public void testChain() throws ExecutionException, InterruptedException {
- AtomicBoolean transiting = new AtomicBoolean(false);
- Service s1 = new DummyService("s1", transiting);
- Service s2 = new DummyService("s2", transiting);
- Service s3 = new DummyService("s3", transiting);
-
- Futures.allAsList(Services.chainStart(s1, s2, s3).get()).get();
- Futures.allAsList(Services.chainStop(s3, s2, s1).get()).get();
- }
-
- @Test
- public void testCompletion() throws ExecutionException, InterruptedException {
- Service service = new DummyService("s1", new AtomicBoolean());
- ListenableFuture<Service.State> completion = Services.getCompletionFuture(service);
-
- service.start();
- service.stop();
-
- completion.get();
-
- AtomicBoolean transiting = new AtomicBoolean();
- service = new DummyService("s2", transiting);
- completion = Services.getCompletionFuture(service);
-
- service.startAndWait();
- transiting.set(true);
- service.stop();
-
- try {
- completion.get();
- Assert.assertTrue(false);
- } catch (ExecutionException e) {
- // Expected
- }
- }
-
- private static final class DummyService extends AbstractIdleService {
-
- private final String name;
- private final AtomicBoolean transiting;
-
- private DummyService(String name, AtomicBoolean transiting) {
- this.name = name;
- this.transiting = transiting;
- }
-
- @Override
- protected void startUp() throws Exception {
- Preconditions.checkState(transiting.compareAndSet(false, true));
- LOG.info("Starting: " + name);
- TimeUnit.MILLISECONDS.sleep(500);
- LOG.info("Started: " + name);
- Preconditions.checkState(transiting.compareAndSet(true, false));
- }
-
- @Override
- protected void shutDown() throws Exception {
- Preconditions.checkState(transiting.compareAndSet(false, true));
- LOG.info("Stopping: " + name);
- TimeUnit.MILLISECONDS.sleep(500);
- LOG.info("Stopped: " + name);
- Preconditions.checkState(transiting.compareAndSet(true, false));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-twill/blob/0d217b6d/twill-core/src/main/java/org/apache/twill/internal/AbstractExecutionServiceController.java
----------------------------------------------------------------------
diff --git a/twill-core/src/main/java/org/apache/twill/internal/AbstractExecutionServiceController.java b/twill-core/src/main/java/org/apache/twill/internal/AbstractExecutionServiceController.java
index acb6b7b..580a88f 100644
--- a/twill-core/src/main/java/org/apache/twill/internal/AbstractExecutionServiceController.java
+++ b/twill-core/src/main/java/org/apache/twill/internal/AbstractExecutionServiceController.java
@@ -17,33 +17,53 @@
*/
package org.apache.twill.internal;
+import com.google.common.base.Function;
import com.google.common.util.concurrent.AbstractIdleService;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.SettableFuture;
+import com.google.common.util.concurrent.Uninterruptibles;
import org.apache.twill.api.RunId;
import org.apache.twill.api.ServiceController;
import org.apache.twill.common.Threads;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
/**
* An abstract base class for implementing {@link ServiceController} that deal with Service state transition and
* listener callback.
*/
-public abstract class AbstractExecutionServiceController implements ServiceController {
+public abstract class AbstractExecutionServiceController implements ServiceController, Service {
private final RunId runId;
private final ListenerExecutors listenerExecutors;
private final Service serviceDelegate;
+ private final SettableFuture<State> terminationFuture;
protected AbstractExecutionServiceController(RunId runId) {
this.runId = runId;
this.listenerExecutors = new ListenerExecutors();
this.serviceDelegate = new ServiceDelegate();
+ this.terminationFuture = SettableFuture.create();
+ addListener(new ServiceListenerAdapter() {
+ @Override
+ public void failed(State from, Throwable failure) {
+ terminationFuture.setException(failure);
+ }
+
+ @Override
+ public void terminated(State from) {
+ terminationFuture.set(State.TERMINATED);
+ }
+ }, Threads.SAME_THREAD_EXECUTOR);
}
protected abstract void startUp();
@@ -56,6 +76,52 @@ public abstract class AbstractExecutionServiceController implements ServiceContr
}
@Override
+ public Future<? extends ServiceController> terminate() {
+ stop();
+
+ return Futures.transform(terminationFuture, new Function<State, ServiceController>() {
+ @Override
+ public ServiceController apply(State input) {
+ return AbstractExecutionServiceController.this;
+ }
+ });
+ }
+
+ @Override
+ public void onRunning(final Runnable runnable, Executor executor) {
+ addListener(new ServiceListenerAdapter() {
+ @Override
+ public void running() {
+ runnable.run();
+ }
+ }, executor);
+ }
+
+ @Override
+ public void onTerminated(final Runnable runnable, Executor executor) {
+ addListener(new ServiceListenerAdapter() {
+ @Override
+ public void failed(State from, Throwable failure) {
+ runnable.run();
+ }
+
+ @Override
+ public void terminated(State from) {
+ runnable.run();
+ }
+ }, executor);
+ }
+
+ @Override
+ public void awaitTerminated() throws ExecutionException {
+ Uninterruptibles.getUninterruptibly(terminationFuture);
+ }
+
+ @Override
+ public void awaitTerminated(long timeout, TimeUnit timeoutUnit) throws TimeoutException, ExecutionException {
+ Uninterruptibles.getUninterruptibly(terminationFuture, timeout, timeoutUnit);
+ }
+
public final void addListener(Listener listener, Executor executor) {
listenerExecutors.addListener(new ListenerExecutor(listener, executor));
}