Fixes pathological slowness in remote UI logger (GPE).
Before: all logging to remote UI occurred in a synchronous, blocking manner.
After: except for creating top-level loggers, all sub-branches and log events happen asynchronously and are flushed on a background thread.
http://gwt-code-reviews.appspot.com/550801/show
Review by: rdayal
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8242 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
index 2b60808..093ad21 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/MessageTransport.java
@@ -20,6 +20,7 @@
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.MessageType;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response;
+import com.google.gwt.dev.util.Callback;
import java.io.IOException;
import java.io.InputStream;
@@ -29,13 +30,11 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -85,31 +84,23 @@
}
class PendingRequest extends PendingSend {
- private final ReentrantLock lock = new ReentrantLock();
- private final Condition availableResponseCondition = lock.newCondition();
- private Response responseMessage;
- private Exception exception;
+ private final Callback<Response> callback;
private final Message message;
- public PendingRequest(Message message) {
+ PendingRequest(Message message, Callback<Response> callback) {
this.message = message;
+ this.callback = callback;
}
@Override
- public void failed(Exception e) {
+ void failed(Exception e) {
+ assert e != null;
pendingRequestMap.remove(message.getMessageId());
-
- lock.lock();
- try {
- exception = e;
- availableResponseCondition.signal();
- } finally {
- lock.unlock();
- }
+ callback.onError(e);
}
@Override
- public void send(OutputStream outputStream) throws IOException {
+ void send(OutputStream outputStream) throws IOException {
int messageId = message.getMessageId();
pendingRequestMap.put(messageId, this);
message.writeDelimitedTo(outputStream);
@@ -122,50 +113,16 @@
* @param responseMessage the server's response
* @throws InterruptedException
*/
- public void setResponse(Message.Response responseMessage)
- throws InterruptedException {
+ void setResponse(Response responseMessage) {
assert (responseMessage != null);
- lock.lock();
- try {
- if (this.responseMessage != null) {
- throw new IllegalStateException("Response has already been set.");
- }
- this.responseMessage = responseMessage;
- availableResponseCondition.signal();
- } finally {
- lock.unlock();
- }
- }
-
- /**
- * Waits for a response to be returned for a given request.
- *
- * @return the response from the server
- * @throws Exception if an exception occurred while processing the request
- */
- public Response waitForResponse() throws Exception {
- lock.lock();
-
- try {
- while (responseMessage == null && exception == null) {
- availableResponseCondition.await();
- }
-
- if (exception != null) {
- throw exception;
- }
-
- return responseMessage;
- } finally {
- lock.unlock();
- }
+ callback.onDone(responseMessage);
}
}
static class PendingRequestMap {
private final Lock mapLock = new ReentrantLock();
- private final Map<Integer, PendingRequest> requestIdToPendingServerRequest = new HashMap<Integer, PendingRequest>();
private boolean noMoreAdds;
+ private final Map<Integer, PendingRequest> requestIdToPendingServerRequest = new HashMap<Integer, PendingRequest>();
public void blockAdds(Exception e) {
mapLock.lock();
@@ -222,22 +179,28 @@
}
abstract class PendingSend {
- public abstract void failed(Exception e);
+ abstract void failed(Exception e);
- public abstract void send(OutputStream outputStream) throws IOException;
+ abstract void send(OutputStream outputStream) throws IOException;
}
- private static final int DEFAULT_SERVICE_THREADS = 2;
-
+ /**
+ * A callable that does nothing.
+ */
+ private static final Callable<Response> DUMMY_CALLABLE = new Callable<Response>() {
+ public Response call() throws Exception {
+ return null;
+ }
+ };
+ private final InputStream inputStream;
private final AtomicBoolean isStarted = new AtomicBoolean(false);
private final AtomicInteger nextMessageId = new AtomicInteger();
+ private final OutputStream outputStream;
+ private final PendingRequestMap pendingRequestMap = new PendingRequestMap();
private final RequestProcessor requestProcessor;
private final LinkedBlockingQueue<PendingSend> sendQueue = new LinkedBlockingQueue<PendingSend>();
- private final ExecutorService serverRequestExecutor;
- private final PendingRequestMap pendingRequestMap = new PendingRequestMap();
+
private final TerminationCallback terminationCallback;
- private final InputStream inputStream;
- private final OutputStream outputStream;
/**
* Create a new instance using the given streams and request processor.
@@ -256,7 +219,6 @@
this.terminationCallback = terminationCallback;
this.inputStream = inputStream;
this.outputStream = outputStream;
- serverRequestExecutor = Executors.newFixedThreadPool(DEFAULT_SERVICE_THREADS);
}
/**
@@ -266,24 +228,65 @@
*
* @return a {@link Future} that can be used to access the server's response
*/
- public Future<Response> executeRequestAsync(final Request requestMessage) {
- Future<Response> responseFuture = serverRequestExecutor.submit(new Callable<Response>() {
- public Response call() throws Exception {
- Message.Builder messageBuilder = Message.newBuilder();
- int messageId = nextMessageId.getAndIncrement();
- messageBuilder.setMessageId(messageId);
- messageBuilder.setMessageType(Message.MessageType.REQUEST);
- messageBuilder.setRequest(requestMessage);
+ public Future<Response> executeRequestAsync(Request requestMessage) {
+ Message.Builder messageBuilder = Message.newBuilder();
+ int messageId = nextMessageId.getAndIncrement();
+ messageBuilder.setMessageId(messageId);
+ messageBuilder.setMessageType(Message.MessageType.REQUEST);
+ messageBuilder.setRequest(requestMessage);
- Message message = messageBuilder.build();
- PendingRequest pendingRequest = new PendingRequest(message);
- sendQueue.put(pendingRequest);
+ Message message = messageBuilder.build();
- return pendingRequest.waitForResponse();
+ class FutureTaskExtension extends FutureTask<Response> {
+ private FutureTaskExtension() {
+ super(DUMMY_CALLABLE);
}
- });
- return responseFuture;
+ public void set(Response v) {
+ super.set(v);
+ }
+
+ public void setException(Throwable t) {
+ super.setException(t);
+ }
+ }
+
+ final FutureTaskExtension future = new FutureTaskExtension();
+ PendingRequest pendingRequest = new PendingRequest(message,
+ new Callback<Response>() {
+
+ public void onDone(Response result) {
+ future.set(result);
+ }
+
+ public void onError(Throwable t) {
+ future.setException(t);
+ }
+ });
+ sendQueue.add(pendingRequest);
+ return future;
+ }
+
+ /**
+ * Asynchronously executes the request on a remote server. The callback will
+ * generally be called by another thread. Memory consistency effects: actions
+ * in a thread prior to calling this method happen-before the callback is
+ * invoked.
+ *
+ * @param requestMessage The request to execute
+ * @param callback The callback to invoke when the response is received
+ */
+ public void executeRequestAsync(Request requestMessage,
+ Callback<Response> callback) {
+ Message.Builder messageBuilder = Message.newBuilder();
+ int messageId = nextMessageId.getAndIncrement();
+ messageBuilder.setMessageId(messageId);
+ messageBuilder.setMessageType(Message.MessageType.REQUEST);
+ messageBuilder.setRequest(requestMessage);
+
+ Message message = messageBuilder.build();
+ PendingRequest pendingRequest = new PendingRequest(message, callback);
+ sendQueue.add(pendingRequest);
}
/**
@@ -351,7 +354,7 @@
} catch (Exception e) {
messageBuilder.setMessageType(Message.MessageType.FAILURE);
Message.Failure.Builder failureMessage = Message.Failure.newBuilder();
-
+
failureMessage.setMessage(e.getLocalizedMessage() != null
? e.getLocalizedMessage() : e.getClass().getName());
StringWriter sw = new StringWriter();
@@ -405,8 +408,7 @@
}
}
- private void processServerResponse(int messageId, Response response)
- throws InterruptedException {
+ private void processServerResponse(int messageId, Response response) {
PendingRequest pendingServerRequest = pendingRequestMap.remove(messageId);
if (pendingServerRequest != null) {
pendingServerRequest.setResponse(response);
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
index 450319c..d69d69c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteUI.java
@@ -72,12 +72,11 @@
String url, String tabKey, String moduleName, String sessionKey,
String agentTag, byte[] agentIcon, Type logLevel) {
- int logHandle;
- logHandle = viewerServiceClient.addModuleLog(remoteSocket, url, tabKey,
- moduleName, sessionKey, agentTag, agentIcon);
+ final int logHandle = viewerServiceClient.addModuleLog(remoteSocket, url,
+ tabKey, moduleName, sessionKey, agentTag, agentIcon);
final ViewerServiceTreeLogger moduleLogger = new ViewerServiceTreeLogger(
viewerServiceClient);
- moduleLogger.setLogHandle(logHandle);
+ moduleLogger.initLogHandle(logHandle);
moduleLogger.setMaxDetail(getLogLevel());
ModuleHandle handle = new ModuleHandle() {
public TreeLogger getLogger() {
@@ -90,11 +89,8 @@
return;
}
}
-
- ViewerServiceTreeLogger moduleLogger = (ViewerServiceTreeLogger) (getLogger());
-
try {
- viewerServiceClient.disconnectLog(moduleLogger.getLogHandle());
+ viewerServiceClient.disconnectLog(logHandle);
} finally {
synchronized (modulesLock) {
modules.remove(this);
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
index e04a3ff..820adfc 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceClient.java
@@ -26,6 +26,7 @@
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Request.ViewerRequest.RequestType;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response.ViewerResponse;
import com.google.gwt.dev.shell.remoteui.RemoteMessageProto.Message.Response.ViewerResponse.CapabilityExchange.Capability;
+import com.google.gwt.dev.util.Callback;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import java.util.List;
@@ -41,6 +42,15 @@
*/
public class ViewerServiceClient {
+ private static final Callback<Response> DUMMY_CALLBACK = new Callback<Response>() {
+ public void onDone(Response result) {
+ }
+
+ public void onError(Throwable t) {
+ // TODO(rdayal): handle errors?
+ }
+ };
+
private final MessageTransport transport;
/**
@@ -56,6 +66,8 @@
/**
* Add an entry that also serves as a log branch.
*
+ * @param indexInParent The index of this entry/branch within the parent
+ * logger
* @param type The severity of the log message.
* @param msg The message.
* @param caught An exception associated with the message
@@ -63,12 +75,11 @@
* information related to the log message
* @param parentLogHandle The log handle of the parent of this log
* entry/branch
- * @param indexInParent The index of this entry/branch within the parent
- * logger
- * @return the log handle of the newly-created branch logger
+ * @param callback the callback to call when a branch handle is available
*/
- public int addLogBranch(Type type, String msg, Throwable caught,
- HelpInfo helpInfo, int parentLogHandle, int indexInParent) {
+ public void addLogBranch(int indexInParent, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo, int parentLogHandle,
+ final Callback<Integer> callback) {
LogData.Builder logDataBuilder = generateLogData(type, msg, caught,
helpInfo);
@@ -85,16 +96,21 @@
Request requestMessage = buildRequestMessageFromViewerRequest(
viewerRequestBuilder).build();
- Future<Response> responseFuture = transport.executeRequestAsync(requestMessage);
+ transport.executeRequestAsync(requestMessage, new Callback<Response>() {
+ public void onDone(Response result) {
+ callback.onDone(result.getViewerResponse().getAddLogBranch().getLogHandle());
+ }
- return waitForResponseOrThrowUncheckedException(responseFuture).getViewerResponse().getAddLogBranch().getLogHandle();
+ public void onError(Throwable t) {
+ callback.onError(t);
+ }
+ });
}
/**
* Add a log entry.
*
- * @param indexOfLogEntryWithinParentLogger The index of this entry within the
- * parent logger
+ * @param indexInParent The index of this entry within the parent logger
* @param type The severity of the log message.
* @param msg The message.
* @param caught An exception associated with the message
@@ -102,14 +118,14 @@
* information related to the log message
* @param logHandle The log handle of the parent of this log entry/branch
*/
- public void addLogEntry(int indexOfLogEntryWithinParentLogger, Type type,
- String msg, Throwable caught, HelpInfo helpInfo, int logHandle) {
+ public void addLogEntry(int indexInParent, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo, int logHandle) {
LogData.Builder logDataBuilder = generateLogData(type, msg, caught,
helpInfo);
ViewerRequest.AddLogEntry.Builder addLogEntryBuilder = ViewerRequest.AddLogEntry.newBuilder();
addLogEntryBuilder.setLogHandle(logHandle);
- addLogEntryBuilder.setIndexInLog(indexOfLogEntryWithinParentLogger);
+ addLogEntryBuilder.setIndexInLog(indexInParent);
addLogEntryBuilder.setLogData(logDataBuilder);
ViewerRequest.Builder viewerRequestBuilder = ViewerRequest.newBuilder();
@@ -119,8 +135,7 @@
Request requestMessage = buildRequestMessageFromViewerRequest(
viewerRequestBuilder).build();
- Future<Response> responseFuture = transport.executeRequestAsync(requestMessage);
- waitForResponseOrThrowUncheckedException(responseFuture);
+ transport.executeRequestAsync(requestMessage, DUMMY_CALLBACK);
}
/**
diff --git a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
index 734d41a..ea00347 100644
--- a/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
+++ b/dev/core/src/com/google/gwt/dev/shell/remoteui/ViewerServiceTreeLogger.java
@@ -15,14 +15,67 @@
*/
package com.google.gwt.dev.shell.remoteui;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.util.Callback;
+import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
+import java.util.List;
+
/**
* A tree logger that creates log entries using a ViewerService.
*/
public final class ViewerServiceTreeLogger extends AbstractTreeLogger {
- private int logHandle = -1;
+ private abstract class Pending {
+ protected final Throwable caught;
+ protected final HelpInfo helpInfo;
+ protected final String msg;
+ protected final TreeLogger.Type type;
+
+ public Pending(Type type, String msg, Throwable caught, HelpInfo helpInfo) {
+ this.caught = caught;
+ this.msg = msg;
+ this.type = type;
+ this.helpInfo = helpInfo;
+ }
+
+ public abstract void send();
+ }
+
+ private class PendingBranch extends Pending {
+ public final ViewerServiceTreeLogger branch;
+
+ public PendingBranch(ViewerServiceTreeLogger branch, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo) {
+ super(type, msg, caught, helpInfo);
+ this.branch = branch;
+ }
+
+ @Override
+ public void send() {
+ sendBranch(branch, type, msg, caught, helpInfo);
+ }
+ }
+
+ private class PendingLog extends Pending {
+ protected final int indexOfLogEntry;
+
+ public PendingLog(int indexOfLogEntry, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo) {
+ super(type, msg, caught, helpInfo);
+ this.indexOfLogEntry = indexOfLogEntry;
+ }
+
+ public void send() {
+ sendEntry(indexOfLogEntry, type, msg, caught, helpInfo);
+ }
+ }
+
+ private volatile int logHandle = -1;
+
+ private List<Pending> pending = Lists.create();
+
private final ViewerServiceClient viewerServiceClient;
/**
@@ -40,43 +93,71 @@
* been set as yet; it will only be set once the branch is committed.
*/
@Override
- public AbstractTreeLogger doBranch() {
- ViewerServiceTreeLogger childLogger = new ViewerServiceTreeLogger(
- viewerServiceClient);
- return childLogger;
- }
-
- /**
- * Commits the branch, and sets the log handle of the branch logger.
- */
- @Override
- public void doCommitBranch(AbstractTreeLogger childBeingCommitted, Type type,
- String msg, Throwable caught, HelpInfo helpInfo) {
- int branchLogHandle = viewerServiceClient.addLogBranch(type, msg, caught,
- helpInfo, getLogHandle(), childBeingCommitted.getBranchedIndex());
- ((ViewerServiceTreeLogger) childBeingCommitted).setLogHandle(branchLogHandle);
+ protected AbstractTreeLogger doBranch() {
+ return new ViewerServiceTreeLogger(viewerServiceClient);
}
@Override
- public void doLog(int indexOfLogEntryWithinParentLogger, Type type,
- String msg, Throwable caught, HelpInfo helpInfo) {
- viewerServiceClient.addLogEntry(indexOfLogEntryWithinParentLogger, type,
- msg, caught, helpInfo, getLogHandle());
+ protected void doCommitBranch(AbstractTreeLogger childBeingCommitted,
+ Type type, String msg, Throwable caught, HelpInfo helpInfo) {
+ // Already synchronized via superclass.
+ ViewerServiceTreeLogger child = (ViewerServiceTreeLogger) childBeingCommitted;
+ if (isSent()) {
+ // Immediately send the child branch.
+ sendBranch(child, type, msg, caught, helpInfo);
+ } else {
+ // Queue the child branch until I'm committed.
+ pending = Lists.add(pending, new PendingBranch(child, type, msg, caught,
+ helpInfo));
+ }
}
- /**
- * Get the handle of this logger. The handle is generated by the viewer
- * service when this logger is first created. If this logger was created as a
- * branch of another logger, then the handle will not be available until the
- * branch has been committed.
- *
- * @return the handle for this logger, or -1 if it has not been set
- */
- public int getLogHandle() {
- return logHandle;
+ @Override
+ protected void doLog(int indexOfLogEntry, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo) {
+ // Already synchronized via superclass.
+ if (isSent()) {
+ // Immediately send the child log entry.
+ sendEntry(indexOfLogEntry, type, msg, caught, helpInfo);
+ } else {
+ // Queue the log entry until I'm committed.
+ pending = Lists.add(pending, new PendingLog(indexOfLogEntry, type, msg,
+ caught, helpInfo));
+ }
}
- public void setLogHandle(int logHandle) {
- this.logHandle = logHandle;
+ synchronized void initLogHandle(int newLogHandle) {
+ assert !isSent();
+ logHandle = newLogHandle;
+ for (Pending item : pending) {
+ item.send();
+ }
+ pending = null;
+ }
+
+ void sendBranch(final ViewerServiceTreeLogger branch, Type type, String msg,
+ Throwable caught, HelpInfo helpInfo) {
+ assert isSent();
+ viewerServiceClient.addLogBranch(branch.getBranchedIndex(), type, msg,
+ caught, helpInfo, logHandle, new Callback<Integer>() {
+ public void onDone(Integer result) {
+ branch.initLogHandle(result);
+ }
+
+ public void onError(Throwable t) {
+ // TODO(rdayal): handle errors?
+ }
+ });
+ }
+
+ void sendEntry(int indexOfLogEntry, Type type, String msg, Throwable caught,
+ HelpInfo helpInfo) {
+ assert isSent();
+ viewerServiceClient.addLogEntry(indexOfLogEntry, type, msg, caught,
+ helpInfo, logHandle);
+ }
+
+ private boolean isSent() {
+ return logHandle >= 0;
}
}
diff --git a/dev/core/src/com/google/gwt/dev/util/Callback.java b/dev/core/src/com/google/gwt/dev/util/Callback.java
new file mode 100644
index 0000000..0dd6380
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/Callback.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 com.google.gwt.dev.util;
+
+/**
+ * Generic callback interface.
+ *
+ * @param <T> the type of the expected result
+ */
+public interface Callback<T> {
+ /**
+ * Called when an operation completes normally.
+ *
+ * @param result the result of the operation
+ */
+ void onDone(T result);
+
+ /**
+ * Called when the task fails to complete.
+ *
+ * @param t the error thrown from the operation
+ */
+ void onError(Throwable t);
+}
diff --git a/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java b/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
index 7f41a84..8a32250 100644
--- a/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/remoteui/MessageTransportTest.java
@@ -12,12 +12,10 @@
import junit.framework.TestCase;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
-import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -66,19 +64,11 @@
}
}
- private static MockNetwork createMockNetwork() throws IOException,
- InterruptedException, ExecutionException {
- final ServerSocket listenSocket = new ServerSocket(0);
- ExecutorService executorService = Executors.newFixedThreadPool(1);
- Future<Socket> future = executorService.submit(new Callable<Socket>() {
- public Socket call() throws Exception {
- return listenSocket.accept();
- }
- });
-
- Socket clientSocket = new Socket("localhost", listenSocket.getLocalPort());
- Socket serverSocket = future.get();
-
+ private static MockNetwork createMockNetwork() throws IOException {
+ InetAddress localHost = InetAddress.getLocalHost();
+ ServerSocket listenSocket = new ServerSocket(0, 1, localHost);
+ Socket clientSocket = new Socket(localHost, listenSocket.getLocalPort());
+ Socket serverSocket = listenSocket.accept();
return new MockNetwork(clientSocket, serverSocket, listenSocket);
}
@@ -91,7 +81,7 @@
* @throws IOException
*/
public void testExecuteAsyncRequestWithClosedServerSocket()
- throws IOException, InterruptedException, ExecutionException {
+ throws IOException, InterruptedException {
MockNetwork network = createMockNetwork();
/*
@@ -237,9 +227,7 @@
* exception on the server side ends up throwing the proper exception via the
* future that the client is waiting on.
*/
- public void testExecuteRequestAsyncServerThrowsException()
- throws InterruptedException, ExecutionException, IOException,
- TimeoutException {
+ public void testExecuteRequestAsyncServerThrowsException() throws IOException {
MockNetwork network = createMockNetwork();
/*
@@ -319,8 +307,7 @@
* @throws ExecutionException
* @throws InterruptedException
*/
- public void testRequestProcessor() throws IOException, InterruptedException,
- ExecutionException {
+ public void testRequestProcessor() throws IOException {
MockNetwork network = createMockNetwork();
// Create the request that will be sent to the server
@@ -390,8 +377,7 @@
* @throws ExecutionException
* @throws InterruptedException
*/
- public void testRequestProcessorThrowsException() throws IOException,
- InterruptedException, ExecutionException {
+ public void testRequestProcessorThrowsException() throws IOException {
MockNetwork network = createMockNetwork();
/*