* Create this object early to avoid possible FuturePing
* verification failure when new threads cannot be created.
*/
FuturePing future = new FuturePing(proxy);
Executor systemThreadPool =
(Executor) (new GetThreadPoolAction(false)).run();
Executor userThreadPool =
(Executor) (new GetThreadPoolAction(true)).run();
/*
* Reserve a few workers in the system thread pool.
*/
ThreadHog systemHog = new ThreadHog(systemThreadPool);
systemHog.hogThreads(10);
/*
* Invoke once to cause a connection to be established.
*/
System.err.println("[invocation #1:]");
proxy.ping();
/*
* Consume all threads with workers in the user thread pool.
*/
ThreadHog userHog = new ThreadHog(userThreadPool);
userHog.hogAllThreads();
/*
* Invocation should fail because the user thread pool has no
* idle threads and no new threads can be created.
*/
System.err.println("[invocation #2:]");
try {
proxy.ping();
throw new Error("unexpected success");
} catch (Throwable t) {
t.printStackTrace();
}
/*
* Release workers in the user thread pool: now tasks can be
* executed in it, but its idle workers will still prevent
* other threads from being created (like for other pools).
*/
userHog.releaseAll();
Thread.sleep(1000);
/*
* Verify that invocations can succeed again.
*/
System.err.println("[invocation #3:]");
proxy.ping();
/*
* Corrupt connection protocol so that on the next request
* attempt, the server side will detect a protocol violation
* and shut down the connection.
*/
if (useNIO) {
sf.lastSocket.getChannel().write(
(ByteBuffer) ByteBuffer.allocate(1).put((byte) 0x00).flip());
} else {
sf.lastSocket.getOutputStream().write(0x00);
}
/*
* Attempt to invoke again asynchronously. This invocation
* may block for now, because when the connection is shut down
* due to the protocol violation, the task to shut down the
* associated sessions asynchronously cannot be executed
* because the system thread pool has no idle threads and no
* new threads can be created).
*/
System.err.println("[invocation #4:]");
userThreadPool.execute(future, "ping");
Thread.sleep(1000);
/*
* Release workers in the system thread pool.
*/