394854 Implemented Promise
This commit is contained in:
parent
3393108950
commit
7737dc8c76
|
@ -58,6 +58,7 @@ import org.eclipse.jetty.io.ssl.SslConnection;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -340,7 +341,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
destination.send(request, listeners);
|
||||
}
|
||||
|
||||
protected void newConnection(HttpDestination destination, Callback<Connection> callback)
|
||||
protected void newConnection(HttpDestination destination, Promise<Connection> promise)
|
||||
{
|
||||
SocketChannel channel = null;
|
||||
try
|
||||
|
@ -353,14 +354,14 @@ public class HttpClient extends ContainerLifeCycle
|
|||
channel.configureBlocking(false);
|
||||
channel.connect(destination.getConnectAddress());
|
||||
|
||||
Future<Connection> result = new ConnectionCallback(destination, callback);
|
||||
Future<Connection> result = new ConnectionCallback(destination, promise);
|
||||
selectorManager.connect(channel, result);
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
if (channel != null)
|
||||
close(channel);
|
||||
callback.failed(null, x);
|
||||
callback.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,7 +644,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
if (sslContextFactory == null)
|
||||
{
|
||||
IOException failure = new ConnectException("Missing " + SslContextFactory.class.getSimpleName() + " for " + destination.getScheme() + " requests");
|
||||
callback.failed(null, failure);
|
||||
callback.failed(failure);
|
||||
throw failure;
|
||||
}
|
||||
else
|
||||
|
@ -659,7 +660,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
// TODO: configureConnection, see above
|
||||
|
||||
appEndPoint.setConnection(connection);
|
||||
callback.callback.completed(connection);
|
||||
callback.callback.succeeded();
|
||||
|
||||
return sslConnection;
|
||||
}
|
||||
|
@ -668,7 +669,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
{
|
||||
HttpConnection connection = new HttpConnection(HttpClient.this, endPoint, destination);
|
||||
// TODO: configureConnection, see above
|
||||
callback.callback.completed(connection);
|
||||
callback.callback.succeeded();
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
@ -677,7 +678,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
|
||||
{
|
||||
ConnectionCallback callback = (ConnectionCallback)attachment;
|
||||
callback.callback.failed(null, ex);
|
||||
callback.callback.failed(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.eclipse.jetty.http.HttpMethod;
|
|||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -158,14 +160,14 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
|
||||
public Future<Connection> newConnection()
|
||||
{
|
||||
FutureCallback<Connection> result = new FutureCallback<>();
|
||||
FuturePromise<Connection> result = new FuturePromise<>();
|
||||
newConnection(new CONNECTCallback(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void newConnection(Callback<Connection> callback)
|
||||
protected void newConnection(Promise<Connection> promise)
|
||||
{
|
||||
client.newConnection(this, callback);
|
||||
client.newConnection(this, promise);
|
||||
}
|
||||
|
||||
protected Connection acquire()
|
||||
|
@ -194,13 +196,13 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
CONNECTCallback connectCallback = new CONNECTCallback(new Callback<Connection>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Connection connection)
|
||||
public void succeeded()
|
||||
{
|
||||
process(connection, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(final Connection connection, final Throwable x)
|
||||
public void failed(final Throwable x)
|
||||
{
|
||||
client.getExecutor().execute(new Runnable()
|
||||
{
|
||||
|
@ -214,7 +216,7 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
});
|
||||
}
|
||||
});
|
||||
newConnection(new TCPCallback(next, maxConnections, connectCallback));
|
||||
newConnection(new TCPPromise(next, maxConnections, connectCallback));
|
||||
// Try again the idle connections
|
||||
return idleConnections.poll();
|
||||
}
|
||||
|
@ -425,13 +427,13 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
}
|
||||
}
|
||||
|
||||
private class TCPCallback implements Callback<Connection>
|
||||
private class TCPPromise implements Promise<Connection>
|
||||
{
|
||||
private final int current;
|
||||
private final int max;
|
||||
private final Callback<Connection> delegate;
|
||||
private final Promise<Connection> delegate;
|
||||
|
||||
private TCPCallback(int current, int max, Callback<Connection> delegate)
|
||||
private TCPPromise(int current, int max, Promise<Connection> delegate)
|
||||
{
|
||||
this.current = current;
|
||||
this.max = max;
|
||||
|
@ -439,32 +441,32 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Connection connection)
|
||||
public void succeeded(Connection connection)
|
||||
{
|
||||
LOG.debug("Created connection {}/{} {} for {}", current, max, connection, HttpDestination.this);
|
||||
delegate.completed(connection);
|
||||
delegate.succeeded(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Connection connection, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
LOG.debug("Connection failed {} for {}", x, HttpDestination.this);
|
||||
connectionCount.decrementAndGet();
|
||||
delegate.failed(connection, x);
|
||||
delegate.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
private class CONNECTCallback implements Callback<Connection>
|
||||
private class CONNECTCallback implements Promise<Connection>
|
||||
{
|
||||
private final Callback<Connection> delegate;
|
||||
private final Promise<Connection> delegate;
|
||||
|
||||
private CONNECTCallback(Callback<Connection> delegate)
|
||||
private CONNECTCallback(Promise<Connection> delegate)
|
||||
{
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed(Connection connection)
|
||||
public void succeeded(Connection connection)
|
||||
{
|
||||
boolean tunnel = isProxied() &&
|
||||
"https".equalsIgnoreCase(getScheme()) &&
|
||||
|
@ -472,13 +474,13 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
if (tunnel)
|
||||
tunnel(connection);
|
||||
else
|
||||
delegate.completed(connection);
|
||||
delegate.succeeded(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Connection connection, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
delegate.failed(connection, x);
|
||||
delegate.failed(x);
|
||||
}
|
||||
|
||||
private void tunnel(final Connection connection)
|
||||
|
@ -496,15 +498,15 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
{
|
||||
if (result.isFailed())
|
||||
{
|
||||
failed(connection, result.getFailure());
|
||||
failed(result.getFailure());
|
||||
}
|
||||
else
|
||||
{
|
||||
Response response = result.getResponse();
|
||||
if (response.getStatus() == 200)
|
||||
delegate.completed(connection);
|
||||
delegate.succeeded(connection);
|
||||
else
|
||||
failed(connection, new HttpResponseException("Received " + response + " for " + result.getRequest(), response));
|
||||
failed(new HttpResponseException("Received " + response + " for " + result.getRequest(), response));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -201,7 +201,7 @@ public class HttpSender
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void failed(Throwable x)
|
||||
protected void onFailed(Throwable x)
|
||||
{
|
||||
fail(x);
|
||||
}
|
||||
|
@ -215,13 +215,13 @@ public class HttpSender
|
|||
|
||||
write(callback, header, chunk, expect100 ? null : contentInfo.content);
|
||||
|
||||
if (callback.pending())
|
||||
if (callback.isPending())
|
||||
{
|
||||
LOG.debug("Write pending for {}", request);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback.completed())
|
||||
if (callback.isSucceeded())
|
||||
{
|
||||
if (!commit(request))
|
||||
return;
|
||||
|
@ -274,7 +274,7 @@ public class HttpSender
|
|||
}
|
||||
}
|
||||
|
||||
private void write(Callback<Void> callback, ByteBuffer header, ByteBuffer chunk, ByteBuffer content)
|
||||
private void write(Callback callback, ByteBuffer header, ByteBuffer chunk, ByteBuffer content)
|
||||
{
|
||||
int mask = 0;
|
||||
if (header != null)
|
||||
|
@ -288,28 +288,28 @@ public class HttpSender
|
|||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
endPoint.write(null, callback, BufferUtil.EMPTY_BUFFER);
|
||||
endPoint.write(callback, BufferUtil.EMPTY_BUFFER);
|
||||
break;
|
||||
case 1:
|
||||
endPoint.write(null, callback, header);
|
||||
endPoint.write(callback, header);
|
||||
break;
|
||||
case 2:
|
||||
endPoint.write(null, callback, chunk);
|
||||
endPoint.write(callback, chunk);
|
||||
break;
|
||||
case 3:
|
||||
endPoint.write(null, callback, header, chunk);
|
||||
endPoint.write(callback, header, chunk);
|
||||
break;
|
||||
case 4:
|
||||
endPoint.write(null, callback, content);
|
||||
endPoint.write(callback, content);
|
||||
break;
|
||||
case 5:
|
||||
endPoint.write(null, callback, header, content);
|
||||
endPoint.write(callback, header, content);
|
||||
break;
|
||||
case 6:
|
||||
endPoint.write(null, callback, chunk, content);
|
||||
endPoint.write(callback, chunk, content);
|
||||
break;
|
||||
case 7:
|
||||
endPoint.write(null, callback, header, chunk, content);
|
||||
endPoint.write(callback, header, chunk, content);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
|
@ -448,7 +448,7 @@ public class HttpSender
|
|||
IDLE, SEND, COMMIT, FAILURE
|
||||
}
|
||||
|
||||
private static abstract class StatefulExecutorCallback implements Callback<Void>, Runnable
|
||||
private static abstract class StatefulExecutorCallback implements Callback, Runnable
|
||||
{
|
||||
private final AtomicReference<State> state = new AtomicReference<>(State.INCOMPLETE);
|
||||
private final Executor executor;
|
||||
|
@ -459,7 +459,7 @@ public class HttpSender
|
|||
}
|
||||
|
||||
@Override
|
||||
public final void completed(final Void context)
|
||||
public final void succeeded()
|
||||
{
|
||||
State previous = state.get();
|
||||
while (true)
|
||||
|
@ -481,7 +481,7 @@ public class HttpSender
|
|||
protected abstract void pendingCompleted();
|
||||
|
||||
@Override
|
||||
public final void failed(Void context, final Throwable x)
|
||||
public final void failed(final Throwable x)
|
||||
{
|
||||
State previous = state.get();
|
||||
while (true)
|
||||
|
@ -507,19 +507,19 @@ public class HttpSender
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void failed(Throwable x);
|
||||
protected abstract void onFailed(Throwable x);
|
||||
|
||||
public boolean pending()
|
||||
public boolean isPending()
|
||||
{
|
||||
return state.compareAndSet(State.INCOMPLETE, State.PENDING);
|
||||
}
|
||||
|
||||
public boolean completed()
|
||||
public boolean isSucceeded()
|
||||
{
|
||||
return state.get() == State.COMPLETE;
|
||||
}
|
||||
|
||||
public boolean failed()
|
||||
public boolean isFailed()
|
||||
{
|
||||
return state.get() == State.FAILED;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public abstract class AbstractConnection implements Connection
|
|||
private final long _created=System.currentTimeMillis();
|
||||
private final EndPoint _endPoint;
|
||||
private final Executor _executor;
|
||||
private final Callback<Void> _readCallback;
|
||||
private final Callback _readCallback;
|
||||
private int _inputBufferSize=2048;
|
||||
|
||||
public AbstractConnection(EndPoint endp, Executor executor)
|
||||
|
@ -59,19 +59,19 @@ public abstract class AbstractConnection implements Connection
|
|||
throw new IllegalArgumentException("Executor must not be null!");
|
||||
_endPoint = endp;
|
||||
_executor = executor;
|
||||
_readCallback = new ExecutorCallback<Void>(executor,0)
|
||||
_readCallback = new ExecutorCallback(executor,0)
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
if (executeOnfillable)
|
||||
super.completed(context);
|
||||
super.succeeded();
|
||||
else
|
||||
onCompleted(context);
|
||||
onCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCompleted(Void context)
|
||||
protected void onCompleted()
|
||||
{
|
||||
if (_state.compareAndSet(State.INTERESTED,State.FILLING))
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ public abstract class AbstractConnection implements Connection
|
|||
case FILLING_INTERESTED:
|
||||
if (_state.compareAndSet(State.FILLING_INTERESTED,State.INTERESTED))
|
||||
{
|
||||
getEndPoint().fillInterested(null, _readCallback);
|
||||
getEndPoint().fillInterested(_readCallback);
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
|
@ -111,7 +111,7 @@ public abstract class AbstractConnection implements Connection
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onFailed(Void context, Throwable x)
|
||||
protected void onFailed(Throwable x)
|
||||
{
|
||||
onFillInterestedFailed(x);
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ public abstract class AbstractConnection implements Connection
|
|||
case IDLE:
|
||||
if (_state.compareAndSet(State.IDLE,State.INTERESTED))
|
||||
{
|
||||
getEndPoint().fillInterested(null, _readCallback);
|
||||
getEndPoint().fillInterested(_readCallback);
|
||||
break loop;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -111,16 +111,16 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void fillInterested(C context, Callback<C> callback) throws IllegalStateException
|
||||
public void fillInterested(Callback callback) throws IllegalStateException
|
||||
{
|
||||
notIdle();
|
||||
_fillInterest.register(context, callback);
|
||||
_fillInterest.register(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws IllegalStateException
|
||||
public void write(Callback callback, ByteBuffer... buffers) throws IllegalStateException
|
||||
{
|
||||
_writeFlusher.write(context, callback, buffers);
|
||||
_writeFlusher.write(callback, buffers);
|
||||
}
|
||||
|
||||
protected abstract void onIncompleteFlush();
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.jetty.util.Callback;
|
|||
* <p>A {@link Connection} is associated to an {@link EndPoint} so that I/O events
|
||||
* happening on the {@link EndPoint} can be processed by the {@link Connection}.</p>
|
||||
* <p>A typical implementation of {@link Connection} overrides {@link #onOpen()} to
|
||||
* {@link EndPoint#fillInterested(Object, Callback) set read interest} on the {@link EndPoint},
|
||||
* {@link EndPoint#fillInterested(Callback) set read interest} on the {@link EndPoint},
|
||||
* and when the {@link EndPoint} signals read readyness, this {@link Connection} can
|
||||
* read bytes from the network and interpret them.</p>
|
||||
*/
|
||||
|
|
|
@ -150,6 +150,7 @@ public interface EndPoint extends Closeable
|
|||
/**
|
||||
* Close any backing stream associated with the endpoint
|
||||
*/
|
||||
@Override
|
||||
void close();
|
||||
|
||||
/**
|
||||
|
@ -201,22 +202,20 @@ public interface EndPoint extends Closeable
|
|||
/**
|
||||
* <p>Requests callback methods to be invoked when a call to {@link #fill(ByteBuffer)} would return data or EOF.</p>
|
||||
*
|
||||
* @param context the context to return via the callback
|
||||
* @param callback the callback to call when an error occurs or we are readable.
|
||||
* @throws ReadPendingException if another read operation is concurrent.
|
||||
*/
|
||||
<C> void fillInterested(C context, Callback<C> callback) throws ReadPendingException;
|
||||
void fillInterested(Callback callback) throws ReadPendingException;
|
||||
|
||||
/**
|
||||
* <p>Writes the given buffers via {@link #flush(ByteBuffer...)} and invokes callback methods when either
|
||||
* all the data has been flushed or an error occurs.</p>
|
||||
*
|
||||
* @param context the context to return via the callback
|
||||
* @param callback the callback to call when an error occurs or the write completed.
|
||||
* @param buffers one or more {@link ByteBuffer}s that will be flushed.
|
||||
* @throws WritePendingException if another write operation is concurrent.
|
||||
*/
|
||||
<C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws WritePendingException;
|
||||
void write(Callback callback, ByteBuffer... buffers) throws WritePendingException;
|
||||
|
||||
/**
|
||||
* @return the {@link Connection} associated with this {@link EndPoint}
|
||||
|
|
|
@ -28,15 +28,14 @@ import org.eclipse.jetty.util.Callback;
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* A Utility class to help implement {@link EndPoint#fillInterested(Object, Callback)}
|
||||
* A Utility class to help implement {@link EndPoint#fillInterested(Callback)}
|
||||
* by keeping state and calling the context and callback objects.
|
||||
*
|
||||
*/
|
||||
public abstract class FillInterest
|
||||
{
|
||||
private final AtomicBoolean _interested = new AtomicBoolean(false);
|
||||
private volatile Callback<Object> _callback;
|
||||
private Object _context;
|
||||
private volatile Callback _callback;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected FillInterest()
|
||||
|
@ -51,12 +50,11 @@ public abstract class FillInterest
|
|||
* @param callback
|
||||
* @throws ReadPendingException
|
||||
*/
|
||||
public <C> void register(C context, Callback<C> callback) throws ReadPendingException
|
||||
public <C> void register(Callback callback) throws ReadPendingException
|
||||
{
|
||||
if (!_interested.compareAndSet(false,true))
|
||||
throw new ReadPendingException();
|
||||
_context=context;
|
||||
_callback=(Callback<Object>)callback;
|
||||
_callback=callback;
|
||||
try
|
||||
{
|
||||
if (needsFill())
|
||||
|
@ -75,11 +73,9 @@ public abstract class FillInterest
|
|||
{
|
||||
if (_interested.compareAndSet(true,false))
|
||||
{
|
||||
Callback<Object> callback=_callback;
|
||||
Object context=_context;
|
||||
Callback callback=_callback;
|
||||
_callback=null;
|
||||
_context=null;
|
||||
callback.completed(context);
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,11 +95,9 @@ public abstract class FillInterest
|
|||
{
|
||||
if (_interested.compareAndSet(true,false))
|
||||
{
|
||||
Callback<Object> callback=_callback;
|
||||
Object context=_context;
|
||||
Callback callback=_callback;
|
||||
_callback=null;
|
||||
_context=null;
|
||||
callback.failed(context,cause);
|
||||
callback.failed(cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,11 +106,9 @@ public abstract class FillInterest
|
|||
{
|
||||
if (_interested.compareAndSet(true,false))
|
||||
{
|
||||
Callback<Object> callback=_callback;
|
||||
Object context=_context;
|
||||
Callback callback=_callback;
|
||||
_callback=null;
|
||||
_context=null;
|
||||
callback.failed(context,new ClosedChannelException());
|
||||
callback.failed(new ClosedChannelException());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +116,7 @@ public abstract class FillInterest
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("FillInterest@%x{%b,%s,%s}",hashCode(),_interested.get(),_callback,_context);
|
||||
return String.format("FillInterest@%x{%b,%s}",hashCode(),_interested.get(),_callback);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -342,10 +342,10 @@ public class FilterConnection extends AbstractConnection
|
|||
/* ------------------------------------------------------------ */
|
||||
public class FilteredEndPoint extends AbstractEndPoint
|
||||
{
|
||||
private final Callback<Void> _writeCB = new Callback<Void>()
|
||||
private final Callback _writeCB = new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
if (BufferUtil.isEmpty(_outBuffer))
|
||||
{
|
||||
|
@ -356,7 +356,7 @@ public class FilterConnection extends AbstractConnection
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
if (BufferUtil.isEmpty(_outBuffer))
|
||||
{
|
||||
|
@ -392,7 +392,7 @@ public class FilterConnection extends AbstractConnection
|
|||
getWriteFlusher().completeWrite();
|
||||
}
|
||||
else
|
||||
getEndPoint().write(null,_writeCB,_outBuffer);
|
||||
getEndPoint().write(_writeCB,_outBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -117,7 +117,7 @@ abstract public class WriteFlusher
|
|||
return updated;
|
||||
}
|
||||
|
||||
private void fail(PendingState<?> pending)
|
||||
private void fail(PendingState pending)
|
||||
{
|
||||
State current = _state.get();
|
||||
if (current.getType()==StateType.FAILED)
|
||||
|
@ -237,17 +237,15 @@ abstract public class WriteFlusher
|
|||
*
|
||||
* @param <C>
|
||||
*/
|
||||
private class PendingState<C> extends State
|
||||
private class PendingState extends State
|
||||
{
|
||||
private final C _context;
|
||||
private final Callback<C> _callback;
|
||||
private final Callback _callback;
|
||||
private final ByteBuffer[] _buffers;
|
||||
|
||||
private PendingState(ByteBuffer[] buffers, C context, Callback<C> callback)
|
||||
private PendingState(ByteBuffer[] buffers, Callback callback)
|
||||
{
|
||||
super(StateType.PENDING);
|
||||
_buffers = buffers;
|
||||
_context = context;
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
|
@ -259,13 +257,13 @@ abstract public class WriteFlusher
|
|||
protected void fail(Throwable cause)
|
||||
{
|
||||
if (_callback!=null)
|
||||
_callback.failed(_context, cause);
|
||||
_callback.failed(cause);
|
||||
}
|
||||
|
||||
protected void complete()
|
||||
{
|
||||
if (_callback!=null)
|
||||
_callback.completed(_context);
|
||||
_callback.succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +287,7 @@ abstract public class WriteFlusher
|
|||
* @param buffers the buffers to flush to the endpoint
|
||||
* @param <C> type of the context
|
||||
*/
|
||||
public <C> void write(C context, Callback<C> callback, ByteBuffer... buffers) throws WritePendingException
|
||||
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
|
||||
{
|
||||
if (DEBUG)
|
||||
LOG.debug("write: {} {}", this, BufferUtil.toDetailString(buffers));
|
||||
|
@ -308,11 +306,11 @@ abstract public class WriteFlusher
|
|||
{
|
||||
if (!flushed||BufferUtil.hasContent(b))
|
||||
{
|
||||
PendingState<?> pending=new PendingState<>(buffers, context, callback);
|
||||
PendingState pending=new PendingState(buffers, callback);
|
||||
if (updateState(__WRITING,pending))
|
||||
onIncompleteFlushed();
|
||||
else
|
||||
fail(new PendingState<>(buffers, context, callback));
|
||||
fail(new PendingState(buffers, callback));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +319,7 @@ abstract public class WriteFlusher
|
|||
if (!updateState(__WRITING,__IDLE))
|
||||
ignoreFail();
|
||||
if (callback!=null)
|
||||
callback.completed(context);
|
||||
callback.succeeded();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -330,10 +328,10 @@ abstract public class WriteFlusher
|
|||
if (updateState(__WRITING,__IDLE))
|
||||
{
|
||||
if (callback!=null)
|
||||
callback.failed(context, e);
|
||||
callback.failed(e);
|
||||
}
|
||||
else
|
||||
fail(new PendingState<>(buffers, context, callback));
|
||||
fail(new PendingState(buffers, callback));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,7 +354,7 @@ abstract public class WriteFlusher
|
|||
if (previous.getType()!=StateType.PENDING)
|
||||
return; // failure already handled.
|
||||
|
||||
PendingState<?> pending = (PendingState<?>)previous;
|
||||
PendingState pending = (PendingState)previous;
|
||||
if (!updateState(pending,__COMPLETING))
|
||||
return; // failure already handled.
|
||||
|
||||
|
@ -413,7 +411,7 @@ abstract public class WriteFlusher
|
|||
return;
|
||||
|
||||
case PENDING:
|
||||
PendingState<?> pending = (PendingState<?>)current;
|
||||
PendingState pending = (PendingState)current;
|
||||
if (updateState(pending,__IDLE))
|
||||
{
|
||||
pending.fail(cause);
|
||||
|
|
|
@ -64,11 +64,11 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* methods. They will never block nor schedule any readInterest or write callbacks. If a fill/flush cannot progress either because
|
||||
* of network congestion or waiting for an SSL handshake message, then the fill/flush will simply return with zero bytes filled/flushed.
|
||||
* Specifically, if a flush cannot proceed because it needs to receive a handshake message, then the flush will attempt to fill bytes from the
|
||||
* encrypted endpoint, but if insufficient bytes are read it will NOT call {@link EndPoint#fillInterested(Object, Callback)}.
|
||||
* encrypted endpoint, but if insufficient bytes are read it will NOT call {@link EndPoint#fillInterested(Callback)}.
|
||||
* <p>
|
||||
* It is only the active methods : {@link DecryptedEndPoint#fillInterested(Object, Callback)} and
|
||||
* It is only the active methods : {@link DecryptedEndPoint#fillInterested(Callback)} and
|
||||
* {@link DecryptedEndPoint#write(Object, Callback, ByteBuffer...)} that may schedule callbacks by calling the encrypted
|
||||
* {@link EndPoint#fillInterested(Object, Callback)} and {@link EndPoint#write(Object, Callback, ByteBuffer...)}
|
||||
* {@link EndPoint#fillInterested(Callback)} and {@link EndPoint#write(Object, Callback, ByteBuffer...)}
|
||||
* methods. For normal data handling, the decrypted fillInterest method will result in an encrypted fillInterest and a decrypted
|
||||
* write will result in an encrypted write. However, due to SSL handshaking requirements, it is also possible for a decrypted fill
|
||||
* to call the encrypted write and for the decrypted flush to call the encrypted fillInterested methods.
|
||||
|
@ -259,10 +259,10 @@ public class SslConnection extends AbstractConnection
|
|||
private boolean _cannotAcceptMoreAppDataToFlush;
|
||||
private boolean _underFlown;
|
||||
|
||||
private final Callback<Void> _writeCallback = new Callback<Void>()
|
||||
private final Callback _writeCallback = new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
// This means that a write of encrypted data has completed. Writes are done
|
||||
// only if there is a pending writeflusher or a read needed to write
|
||||
|
@ -287,7 +287,7 @@ public class SslConnection extends AbstractConnection
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
// This means that a write of data has failed. Writes are done
|
||||
// only if there is an active writeflusher or a read needed to write
|
||||
|
@ -354,7 +354,7 @@ public class SslConnection extends AbstractConnection
|
|||
{
|
||||
// write it
|
||||
_cannotAcceptMoreAppDataToFlush = true;
|
||||
getEndPoint().write(null, _writeCallback, _encryptedOutput);
|
||||
getEndPoint().write(_writeCallback, _encryptedOutput);
|
||||
}
|
||||
// TODO: use _fillRequiresFlushToProgress ?
|
||||
else if (_sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP)
|
||||
|
@ -404,7 +404,7 @@ public class SslConnection extends AbstractConnection
|
|||
{
|
||||
// write it
|
||||
_cannotAcceptMoreAppDataToFlush = true;
|
||||
getEndPoint().write(null, _writeCallback, _encryptedOutput);
|
||||
getEndPoint().write(_writeCallback, _encryptedOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -157,45 +157,45 @@ public class ByteArrayEndPointTest
|
|||
endp.setInput("test input");
|
||||
|
||||
ByteBuffer buffer = BufferUtil.allocate(1024);
|
||||
FutureCallback<String> fcb = new FutureCallback<>();
|
||||
FutureCallback fcb = new FutureCallback();
|
||||
|
||||
endp.fillInterested("CTX", fcb);
|
||||
endp.fillInterested(fcb);
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(10, endp.fill(buffer));
|
||||
assertEquals("test input", BufferUtil.toString(buffer));
|
||||
|
||||
fcb = new FutureCallback<>();
|
||||
endp.fillInterested("CTX", fcb);
|
||||
fcb = new FutureCallback();
|
||||
endp.fillInterested(fcb);
|
||||
assertFalse(fcb.isDone());
|
||||
assertEquals(0, endp.fill(buffer));
|
||||
|
||||
endp.setInput(" more");
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(5, endp.fill(buffer));
|
||||
assertEquals("test input more", BufferUtil.toString(buffer));
|
||||
|
||||
fcb = new FutureCallback<>();
|
||||
endp.fillInterested("CTX", fcb);
|
||||
fcb = new FutureCallback();
|
||||
endp.fillInterested(fcb);
|
||||
assertFalse(fcb.isDone());
|
||||
assertEquals(0, endp.fill(buffer));
|
||||
|
||||
endp.setInput((ByteBuffer)null);
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(-1, endp.fill(buffer));
|
||||
|
||||
fcb = new FutureCallback<>();
|
||||
endp.fillInterested("CTX", fcb);
|
||||
fcb = new FutureCallback();
|
||||
endp.fillInterested(fcb);
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(-1, endp.fill(buffer));
|
||||
|
||||
endp.close();
|
||||
|
||||
fcb = new FutureCallback<>();
|
||||
endp.fillInterested("CTX", fcb);
|
||||
fcb = new FutureCallback();
|
||||
endp.fillInterested(fcb);
|
||||
assertTrue(fcb.isDone());
|
||||
try
|
||||
{
|
||||
|
@ -218,21 +218,21 @@ public class ByteArrayEndPointTest
|
|||
ByteBuffer data = BufferUtil.toBuffer("Data.");
|
||||
ByteBuffer more = BufferUtil.toBuffer(" Some more.");
|
||||
|
||||
FutureCallback<String> fcb = new FutureCallback<>();
|
||||
endp.write("CTX", fcb, data);
|
||||
FutureCallback fcb = new FutureCallback();
|
||||
endp.write( fcb, data);
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals("Data.", endp.getOutputString());
|
||||
|
||||
fcb = new FutureCallback<>();
|
||||
endp.write("CTX", fcb, more);
|
||||
fcb = new FutureCallback();
|
||||
endp.write(fcb, more);
|
||||
assertFalse(fcb.isDone());
|
||||
|
||||
assertEquals("Data. Some", endp.getOutputString());
|
||||
assertEquals("Data. Some", endp.takeOutputString());
|
||||
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals("CTX", fcb.get());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(" more.", endp.getOutputString());
|
||||
}
|
||||
|
||||
|
@ -253,17 +253,17 @@ public class ByteArrayEndPointTest
|
|||
|
||||
// normal read
|
||||
ByteBuffer buffer = BufferUtil.allocate(1024);
|
||||
FutureCallback<Void> fcb = new FutureCallback<>();
|
||||
FutureCallback fcb = new FutureCallback();
|
||||
|
||||
endp.fillInterested(null, fcb);
|
||||
endp.fillInterested(fcb);
|
||||
assertTrue(fcb.isDone());
|
||||
assertEquals(null, fcb.get());
|
||||
assertEquals(4, endp.fill(buffer));
|
||||
assertEquals("test", BufferUtil.toString(buffer));
|
||||
|
||||
// read timeout
|
||||
fcb = new FutureCallback<>();
|
||||
endp.fillInterested(null, fcb);
|
||||
fcb = new FutureCallback();
|
||||
endp.fillInterested(fcb);
|
||||
long start = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
|
@ -285,8 +285,8 @@ public class ByteArrayEndPointTest
|
|||
Thread.sleep(idleTimeout / 2);
|
||||
|
||||
// write timeout
|
||||
fcb = new FutureCallback<>();
|
||||
endp.write(null, fcb, BufferUtil.toBuffer("This is too long"));
|
||||
fcb = new FutureCallback();
|
||||
endp.write(fcb, BufferUtil.toBuffer("This is too long"));
|
||||
start = System.currentTimeMillis();
|
||||
try
|
||||
{
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SelectChannelEndPointInterestsTest
|
|||
connection.fillInterested();
|
||||
|
||||
ByteBuffer output = ByteBuffer.allocate(size.get());
|
||||
endPoint.write(null, new Callback.Empty<>(), output);
|
||||
endPoint.write(new Callback.Adapter(), output);
|
||||
|
||||
latch1.countDown();
|
||||
}
|
||||
|
|
|
@ -154,8 +154,8 @@ public class SelectChannelEndPointTest
|
|||
// If the tests wants to block, then block
|
||||
while (_blockAt > 0 && _endp.isOpen() && _in.remaining() < _blockAt)
|
||||
{
|
||||
FutureCallback<Void> blockingRead = new FutureCallback<>();
|
||||
_endp.fillInterested(null, blockingRead);
|
||||
FutureCallback blockingRead = new FutureCallback();
|
||||
_endp.fillInterested(blockingRead);
|
||||
blockingRead.get();
|
||||
filled = _endp.fill(_in);
|
||||
progress |= filled > 0;
|
||||
|
@ -172,8 +172,8 @@ public class SelectChannelEndPointTest
|
|||
BufferUtil.clear(_out);
|
||||
for (int i = 0; i < _writeCount; i++)
|
||||
{
|
||||
FutureCallback<Void> blockingWrite = new FutureCallback<>();
|
||||
_endp.write(null, blockingWrite, out.asReadOnlyBuffer());
|
||||
FutureCallback blockingWrite = new FutureCallback();
|
||||
_endp.write(blockingWrite, out.asReadOnlyBuffer());
|
||||
blockingWrite.get();
|
||||
}
|
||||
progress = true;
|
||||
|
@ -189,8 +189,8 @@ public class SelectChannelEndPointTest
|
|||
// Timeout does not close, so echo exception then shutdown
|
||||
try
|
||||
{
|
||||
FutureCallback<Void> blockingWrite = new FutureCallback<>();
|
||||
_endp.write(null, blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in)));
|
||||
FutureCallback blockingWrite = new FutureCallback();
|
||||
_endp.write(blockingWrite, BufferUtil.toBuffer("EE: " + BufferUtil.toString(_in)));
|
||||
blockingWrite.get();
|
||||
_endp.shutdownOutput();
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public class SelectorManagerTest
|
|||
@Override
|
||||
protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment)
|
||||
{
|
||||
((Callback<Void>)attachment).failed(null, ex);
|
||||
((Callback)attachment).failed(ex);
|
||||
}
|
||||
};
|
||||
selectorManager.setConnectTimeout(connectTimeout);
|
||||
|
@ -114,10 +114,10 @@ public class SelectorManagerTest
|
|||
try
|
||||
{
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
selectorManager.connect(client, new Callback.Empty<Void>()
|
||||
selectorManager.connect(client, new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class SslConnectionTest
|
|||
|
||||
protected volatile EndPoint _lastEndp;
|
||||
private volatile boolean _testFill=true;
|
||||
private volatile FutureCallback<Void> _writeCallback;
|
||||
private volatile FutureCallback _writeCallback;
|
||||
protected ServerSocketChannel _connector;
|
||||
final AtomicInteger _dispatches = new AtomicInteger();
|
||||
protected QueuedThreadPool _threadPool = new QueuedThreadPool()
|
||||
|
@ -156,7 +156,7 @@ public class SslConnectionTest
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
getEndPoint().write(null,_writeCallback,BufferUtil.toBuffer("Hello Client"));
|
||||
getEndPoint().write(_writeCallback,BufferUtil.toBuffer("Hello Client"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -191,8 +191,8 @@ public class SslConnectionTest
|
|||
int l=_in.remaining();
|
||||
if (l>0)
|
||||
{
|
||||
FutureCallback<Void> blockingWrite= new FutureCallback<>();
|
||||
endp.write(null,blockingWrite,_in);
|
||||
FutureCallback blockingWrite= new FutureCallback();
|
||||
endp.write(blockingWrite,_in);
|
||||
blockingWrite.get();
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ public class SslConnectionTest
|
|||
{
|
||||
_testFill=false;
|
||||
|
||||
_writeCallback = new FutureCallback<>();
|
||||
_writeCallback = new FutureCallback();
|
||||
Socket client = newClient();
|
||||
client.setSoTimeout(10000);
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ public class WriteFlusherTest
|
|||
private WriteFlusher _flusher;
|
||||
|
||||
private final AtomicBoolean _flushIncomplete = new AtomicBoolean(false);
|
||||
private final String _context = "Context";
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(16);
|
||||
private ByteArrayEndPoint _endp;
|
||||
|
||||
|
@ -87,12 +86,12 @@ public class WriteFlusherTest
|
|||
{
|
||||
_endp.setGrowOutput(true);
|
||||
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.onFail(new IOException("Ignored because no operation in progress"));
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
assertCallbackIsDone(callback);
|
||||
assertFlushIsComplete();
|
||||
assertThat("context and callback.get() are equal", _context, equalTo(callback.get()));
|
||||
assertThat("context and callback.get() are equal",callback.get() , equalTo(null));
|
||||
assertThat("string in endpoint matches expected string", "How now brown cow!",
|
||||
equalTo(_endp.takeOutputString()));
|
||||
assertTrue(_flusher.isIdle());
|
||||
|
@ -103,11 +102,11 @@ public class WriteFlusherTest
|
|||
{
|
||||
_endp.setGrowOutput(true);
|
||||
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
assertCallbackIsDone(callback);
|
||||
assertFlushIsComplete();
|
||||
assertThat("context and callback.get() are equal", _context, equalTo(callback.get()));
|
||||
assertThat("context and callback.get() are equal", callback.get(), equalTo(null));
|
||||
assertThat("string in endpoint matches expected string", "How now brown cow!",
|
||||
equalTo(_endp.takeOutputString()));
|
||||
assertTrue(_flusher.isIdle());
|
||||
|
@ -118,7 +117,7 @@ public class WriteFlusherTest
|
|||
assertThat("flush is complete", _flushIncomplete.get(), is(false));
|
||||
}
|
||||
|
||||
private void assertCallbackIsDone(FutureCallback<String> callback)
|
||||
private void assertCallbackIsDone(FutureCallback callback)
|
||||
{
|
||||
assertThat("callback is done", callback.isDone(), is(true));
|
||||
}
|
||||
|
@ -128,13 +127,13 @@ public class WriteFlusherTest
|
|||
{
|
||||
_endp.close();
|
||||
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
assertCallbackIsDone(callback);
|
||||
assertFlushIsComplete();
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get());
|
||||
assertEquals(callback.get(),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (ExecutionException e)
|
||||
|
@ -151,15 +150,15 @@ public class WriteFlusherTest
|
|||
@Test
|
||||
public void testCompleteBlocking() throws Exception
|
||||
{
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
assertFalse(callback.isDone());
|
||||
assertFalse(callback.isCancelled());
|
||||
|
||||
assertTrue(_flushIncomplete.get());
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get(10, TimeUnit.MILLISECONDS));
|
||||
assertEquals(callback.get(10, TimeUnit.MILLISECONDS),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (TimeoutException to)
|
||||
|
@ -170,7 +169,7 @@ public class WriteFlusherTest
|
|||
assertEquals("How now br", _endp.takeOutputString());
|
||||
_flusher.completeWrite();
|
||||
assertCallbackIsDone(callback);
|
||||
assertEquals(_context, callback.get());
|
||||
assertEquals(callback.get(),null);
|
||||
assertEquals("own cow!", _endp.takeOutputString());
|
||||
assertFlushIsComplete();
|
||||
assertTrue(_flusher.isIdle());
|
||||
|
@ -179,8 +178,8 @@ public class WriteFlusherTest
|
|||
@Test
|
||||
public void testCloseWhileBlocking() throws Exception
|
||||
{
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
|
||||
assertFalse(callback.isDone());
|
||||
assertFalse(callback.isCancelled());
|
||||
|
@ -188,7 +187,7 @@ public class WriteFlusherTest
|
|||
assertTrue(_flushIncomplete.get());
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get(10, TimeUnit.MILLISECONDS));
|
||||
assertEquals(callback.get(10, TimeUnit.MILLISECONDS),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (TimeoutException to)
|
||||
|
@ -203,7 +202,7 @@ public class WriteFlusherTest
|
|||
assertFlushIsComplete();
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get());
|
||||
assertEquals(callback.get(),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (ExecutionException e)
|
||||
|
@ -219,8 +218,8 @@ public class WriteFlusherTest
|
|||
@Test
|
||||
public void testFailWhileBlocking() throws Exception
|
||||
{
|
||||
FutureCallback<String> callback = new FutureCallback<>();
|
||||
_flusher.write(_context, callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
FutureCallback callback = new FutureCallback();
|
||||
_flusher.write(callback, BufferUtil.toBuffer("How "), BufferUtil.toBuffer("now "), BufferUtil.toBuffer("brown "), BufferUtil.toBuffer("cow!"));
|
||||
|
||||
assertFalse(callback.isDone());
|
||||
assertFalse(callback.isCancelled());
|
||||
|
@ -228,7 +227,7 @@ public class WriteFlusherTest
|
|||
assertTrue(_flushIncomplete.get());
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get(10, TimeUnit.MILLISECONDS));
|
||||
assertEquals(callback.get(10, TimeUnit.MILLISECONDS),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (TimeoutException to)
|
||||
|
@ -243,7 +242,7 @@ public class WriteFlusherTest
|
|||
assertFlushIsComplete();
|
||||
try
|
||||
{
|
||||
assertEquals(_context, callback.get());
|
||||
assertEquals(callback.get(),null);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (ExecutionException e)
|
||||
|
@ -301,7 +300,7 @@ public class WriteFlusherTest
|
|||
|
||||
|
||||
ConcurrentFlusher[] flushers = new ConcurrentFlusher[50000];
|
||||
FutureCallback<?>[] futures = new FutureCallback<?>[flushers.length];
|
||||
FutureCallback[] futures = new FutureCallback[flushers.length];
|
||||
for (int i = 0; i < flushers.length; i++)
|
||||
{
|
||||
int size = 5 + random.nextInt(15);
|
||||
|
@ -309,7 +308,7 @@ public class WriteFlusherTest
|
|||
|
||||
final ConcurrentFlusher flusher = new ConcurrentFlusher(endp, random, scheduler);
|
||||
flushers[i] = flusher;
|
||||
final FutureCallback<String> callback = new FutureCallback<>();
|
||||
final FutureCallback callback = new FutureCallback();
|
||||
futures[i] = callback;
|
||||
scheduler.schedule(new Runnable()
|
||||
{
|
||||
|
@ -320,7 +319,7 @@ public class WriteFlusherTest
|
|||
}
|
||||
}
|
||||
, random.nextInt(75) + 1, TimeUnit.MILLISECONDS);
|
||||
flusher.write(_context, callback, BufferUtil.toBuffer("How Now Brown Cow."), BufferUtil.toBuffer(" The quick brown fox jumped over the lazy dog!"));
|
||||
flusher.write(callback, BufferUtil.toBuffer("How Now Brown Cow."), BufferUtil.toBuffer(" The quick brown fox jumped over the lazy dog!"));
|
||||
}
|
||||
|
||||
int completed = 0;
|
||||
|
@ -359,9 +358,9 @@ public class WriteFlusherTest
|
|||
final WriteFlusher writeFlusher = new WriteFlusher(_endPointMock)
|
||||
{
|
||||
@Override
|
||||
public <C> void write(C context, Callback<C> callback, ByteBuffer... buffers)
|
||||
public void write(Callback callback, ByteBuffer... buffers)
|
||||
{
|
||||
super.write(context, callback, buffers);
|
||||
super.write(callback, buffers);
|
||||
writeCompleteLatch.countDown();
|
||||
}
|
||||
|
||||
|
@ -407,17 +406,17 @@ public class WriteFlusherTest
|
|||
private boolean completed = false;
|
||||
|
||||
@Override
|
||||
public void completed(Object context)
|
||||
public void succeeded()
|
||||
{
|
||||
completed = true;
|
||||
super.completed(context);
|
||||
super.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Object context, Throwable cause)
|
||||
public void failed(Throwable cause)
|
||||
{
|
||||
failed = true;
|
||||
super.failed(context, cause);
|
||||
super.failed(cause);
|
||||
}
|
||||
|
||||
public boolean isFailed()
|
||||
|
@ -457,7 +456,7 @@ public class WriteFlusherTest
|
|||
}
|
||||
});
|
||||
|
||||
executor.submit(new Writer(writeFlusher, new FutureCallback<String>()));
|
||||
executor.submit(new Writer(writeFlusher, new FutureCallback()));
|
||||
// make sure that we call .get() on the write that executed second by waiting on this latch
|
||||
assertThat("Flush has been called once", flushCalledLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
try
|
||||
|
@ -475,12 +474,9 @@ public class WriteFlusherTest
|
|||
{
|
||||
when(_endPointMock.flush(any(ByteBuffer[].class))).thenAnswer(new Answer<Object>()
|
||||
{
|
||||
int called = 0;
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
{
|
||||
called++;
|
||||
Object[] arguments = invocation.getArguments();
|
||||
ByteBuffer byteBuffer = (ByteBuffer)arguments[0];
|
||||
BufferUtil.flipToFill(byteBuffer); // pretend everything has been written
|
||||
|
@ -492,8 +488,7 @@ public class WriteFlusherTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testConcurrentAccessToIncompleteWriteAndOnFail() throws IOException, InterruptedException,
|
||||
ExecutionException, TimeoutException
|
||||
public void testConcurrentAccessToIncompleteWriteAndOnFail() throws Exception
|
||||
{
|
||||
final CountDownLatch failedCalledLatch = new CountDownLatch(1);
|
||||
final CountDownLatch onIncompleteFlushedCalledLatch = new CountDownLatch(1);
|
||||
|
@ -502,6 +497,7 @@ public class WriteFlusherTest
|
|||
|
||||
final WriteFlusher writeFlusher = new WriteFlusher(new EndPointMock(writeCalledLatch, failedCalledLatch))
|
||||
{
|
||||
@Override
|
||||
protected void onIncompleteFlushed()
|
||||
{
|
||||
onIncompleteFlushedCalledLatch.countDown();
|
||||
|
@ -578,7 +574,7 @@ public class WriteFlusherTest
|
|||
}
|
||||
}
|
||||
|
||||
private static class FailedCaller implements Callable
|
||||
private static class FailedCaller implements Callable<FutureCallback>
|
||||
{
|
||||
private final WriteFlusher writeFlusher;
|
||||
private CountDownLatch failedCalledLatch;
|
||||
|
@ -598,12 +594,12 @@ public class WriteFlusherTest
|
|||
}
|
||||
}
|
||||
|
||||
private class Writer implements Callable
|
||||
private class Writer implements Callable<FutureCallback>
|
||||
{
|
||||
private final WriteFlusher writeFlusher;
|
||||
private FutureCallback<String> callback;
|
||||
private FutureCallback callback;
|
||||
|
||||
public Writer(WriteFlusher writeFlusher, FutureCallback<String> callback)
|
||||
public Writer(WriteFlusher writeFlusher, FutureCallback callback)
|
||||
{
|
||||
this.writeFlusher = writeFlusher;
|
||||
this.callback = callback;
|
||||
|
@ -612,7 +608,7 @@ public class WriteFlusherTest
|
|||
@Override
|
||||
public FutureCallback call()
|
||||
{
|
||||
writeFlusher.write(_context, callback, BufferUtil.toBuffer("foo"));
|
||||
writeFlusher.write(callback, BufferUtil.toBuffer("foo"));
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -264,9 +264,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> Future<C> shutdown(C c)
|
||||
public Future<Void> shutdown()
|
||||
{
|
||||
return new FutureCallback<C>(c);
|
||||
return new FutureCallback(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -102,10 +102,10 @@ public abstract class AbstractNetworkConnector extends AbstractConnector impleme
|
|||
|
||||
|
||||
@Override
|
||||
public <C> Future<C> shutdown(C c)
|
||||
public Future<Void> shutdown()
|
||||
{
|
||||
close();
|
||||
return super.shutdown(c);
|
||||
return super.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -413,16 +413,16 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void send(ResponseInfo info, ByteBuffer content, boolean lastContent, C context, Callback<C> callback)
|
||||
public void send(ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
send(info,content,lastContent);
|
||||
callback.completed(context);
|
||||
callback.succeeded();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
callback.failed(context,e);
|
||||
callback.failed(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,7 +430,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
|
|||
{
|
||||
try
|
||||
{
|
||||
getEndPoint().write(_writeBlocker.getPhase(), _writeBlocker, bytes);
|
||||
getEndPoint().write(_writeBlocker, bytes);
|
||||
_writeBlocker.block();
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
|
@ -557,7 +557,7 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
|
|||
}
|
||||
|
||||
// Wait until we can read
|
||||
getEndPoint().fillInterested(_readBlocker.getPhase(),_readBlocker);
|
||||
getEndPoint().fillInterested(_readBlocker);
|
||||
LOG.debug("{} block readable on {}",this,_readBlocker);
|
||||
_readBlocker.block();
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ public interface HttpTransport
|
|||
{
|
||||
void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent) throws IOException;
|
||||
|
||||
<C> void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, C context, Callback<C> callback);
|
||||
void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback);
|
||||
|
||||
void completed();
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class LocalConnector extends AbstractConnector
|
|||
|
||||
public LocalConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory sslContextFactory)
|
||||
{
|
||||
this(server, null, null, null, 0,AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory));
|
||||
this(server, null, null, null, 0, AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -321,12 +321,12 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
|
||||
// First close the network connectors to stop accepting new connections
|
||||
for (Connector connector : _connectors)
|
||||
futures.add(connector.shutdown((Void)null));
|
||||
futures.add(connector.shutdown());
|
||||
|
||||
// Then tell the contexts that we are shutting down
|
||||
Handler[] contexts = getChildHandlersByClass(Graceful.class);
|
||||
for (Handler context : contexts)
|
||||
futures.add(((Graceful)context).shutdown((Void)null));
|
||||
futures.add(((Graceful)context).shutdown());
|
||||
|
||||
// Shall we gracefully wait for zero connections?
|
||||
long stopTimeout = getStopTimeout();
|
||||
|
|
|
@ -66,7 +66,7 @@ import org.eclipse.jetty.util.thread.Scheduler;
|
|||
* The connector will use the {@link Executor} service to execute a number of Selector Tasks,
|
||||
* which are implemented to each use a NIO {@link Selector} instance to asynchronously
|
||||
* schedule a set of accepted connections. It is the selector thread that will call the
|
||||
* {@link Callback} instances passed in the {@link EndPoint#fillInterested(Object, Callback)} or
|
||||
* {@link Callback} instances passed in the {@link EndPoint#fillInterested(Callback)} or
|
||||
* {@link EndPoint#write(Object, Callback, java.nio.ByteBuffer...)} methods. It is expected
|
||||
* that these callbacks may do some non-blocking IO work, but will always dispatch to the
|
||||
* {@link Executor} service any blocking, long running or application tasks.
|
||||
|
@ -242,10 +242,10 @@ public class ServerConnector extends AbstractNetworkConnector
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> Future<C> shutdown(C c)
|
||||
public Future<Void> shutdown()
|
||||
{
|
||||
// TODO shutdown all the connections
|
||||
return super.shutdown(c);
|
||||
return super.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -360,12 +360,11 @@ public class ConnectHandler extends HandlerWrapper
|
|||
*
|
||||
* @param endPoint the endPoint to read from
|
||||
* @param buffer the buffer to read data into
|
||||
* @param context the context information related to the connection
|
||||
* @return the number of bytes read (possibly 0 since the read is non-blocking)
|
||||
* or -1 if the channel has been closed remotely
|
||||
* @throws IOException if the endPoint cannot be read
|
||||
*/
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer) throws IOException
|
||||
{
|
||||
return endPoint.fill(buffer);
|
||||
}
|
||||
|
@ -375,13 +374,12 @@ public class ConnectHandler extends HandlerWrapper
|
|||
*
|
||||
* @param endPoint the endPoint to write to
|
||||
* @param buffer the buffer to write
|
||||
* @param context the context information related to the connection
|
||||
* @param callback the completion callback to invoke
|
||||
*/
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context, Callback<Void> callback)
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, Callback callback)
|
||||
{
|
||||
LOG.debug("{} writing {} bytes", this, buffer.remaining());
|
||||
endPoint.write(null, callback, buffer);
|
||||
endPoint.write(callback, buffer);
|
||||
}
|
||||
|
||||
public Set<String> getWhiteListHosts()
|
||||
|
@ -523,15 +521,15 @@ public class ConnectHandler extends HandlerWrapper
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer) throws IOException
|
||||
{
|
||||
return ConnectHandler.this.read(endPoint, buffer, context);
|
||||
return ConnectHandler.this.read(endPoint, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context, Callback<Void> callback)
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer,Callback callback)
|
||||
{
|
||||
ConnectHandler.this.write(endPoint, buffer, context, callback);
|
||||
ConnectHandler.this.write(endPoint, buffer, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,17 +548,17 @@ public class ConnectHandler extends HandlerWrapper
|
|||
{
|
||||
super.onOpen();
|
||||
final int remaining = buffer.remaining();
|
||||
write(getConnection().getEndPoint(), buffer, getContext(), new Callback<Void>()
|
||||
write(getConnection().getEndPoint(), buffer, new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
LOG.debug("{} wrote initial {} bytes to server", DownstreamConnection.this, remaining);
|
||||
fillInterested();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
LOG.debug(this + " failed to write initial " + remaining + " bytes to server", x);
|
||||
close();
|
||||
|
@ -570,15 +568,15 @@ public class ConnectHandler extends HandlerWrapper
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer) throws IOException
|
||||
{
|
||||
return ConnectHandler.this.read(endPoint, buffer, context);
|
||||
return ConnectHandler.this.read(endPoint, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context, Callback<Void> callback)
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, Callback callback)
|
||||
{
|
||||
ConnectHandler.this.write(endPoint, buffer, context, callback);
|
||||
ConnectHandler.this.write(endPoint, buffer, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -626,11 +626,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
*
|
||||
*/
|
||||
@Override
|
||||
public <C> Future<C> shutdown(final C c)
|
||||
public Future<Void> shutdown()
|
||||
{
|
||||
_availability = isRunning() ? Availability.SHUTDOWN : Availability.UNAVAILABLE;
|
||||
|
||||
return new FutureCallback<>(c);
|
||||
return new FutureCallback(true);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
public abstract class ProxyConnection extends AbstractConnection
|
||||
{
|
||||
protected static final Logger LOG = ConnectHandler.LOG;
|
||||
private final ForkInvoker<ByteBuffer> invoker = new ProxyForkInvoker();
|
||||
private final ForkInvoker<Void> invoker = new ProxyForkInvoker();
|
||||
private final ByteBufferPool bufferPool;
|
||||
private final ConcurrentMap<String, Object> context;
|
||||
private Connection connection;
|
||||
|
@ -69,30 +69,25 @@ public abstract class ProxyConnection extends AbstractConnection
|
|||
@Override
|
||||
public void onFillable()
|
||||
{
|
||||
ByteBuffer buffer = getByteBufferPool().acquire(getInputBufferSize(), true);
|
||||
fill(buffer);
|
||||
}
|
||||
|
||||
private void fill(final ByteBuffer buffer)
|
||||
{
|
||||
final ByteBuffer buffer = getByteBufferPool().acquire(getInputBufferSize(), true);
|
||||
try
|
||||
{
|
||||
final int filled = read(getEndPoint(), buffer, getContext());
|
||||
final int filled = read(getEndPoint(), buffer);
|
||||
LOG.debug("{} filled {} bytes", this, filled);
|
||||
if (filled > 0)
|
||||
{
|
||||
write(getConnection().getEndPoint(), buffer, getContext(), new Callback<Void>()
|
||||
write(getConnection().getEndPoint(), buffer, new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
LOG.debug("{} wrote {} bytes", this, filled);
|
||||
buffer.clear();
|
||||
invoker.invoke(buffer);
|
||||
bufferPool.release(buffer);
|
||||
invoker.invoke(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
LOG.debug(this + " failed to write " + filled + " bytes", x);
|
||||
bufferPool.release(buffer);
|
||||
|
@ -120,9 +115,9 @@ public abstract class ProxyConnection extends AbstractConnection
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException;
|
||||
protected abstract int read(EndPoint endPoint, ByteBuffer buffer) throws IOException;
|
||||
|
||||
protected abstract void write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context, Callback<Void> callback);
|
||||
protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback);
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
|
@ -133,7 +128,7 @@ public abstract class ProxyConnection extends AbstractConnection
|
|||
getEndPoint().getRemoteAddress().getPort());
|
||||
}
|
||||
|
||||
private class ProxyForkInvoker extends ForkInvoker<ByteBuffer>
|
||||
private class ProxyForkInvoker extends ForkInvoker<Void> implements Runnable
|
||||
{
|
||||
private ProxyForkInvoker()
|
||||
{
|
||||
|
@ -141,22 +136,21 @@ public abstract class ProxyConnection extends AbstractConnection
|
|||
}
|
||||
|
||||
@Override
|
||||
public void fork(final ByteBuffer buffer)
|
||||
public void fork(Void arg)
|
||||
{
|
||||
getExecutor().execute(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
call(buffer);
|
||||
}
|
||||
});
|
||||
getExecutor().execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
onFillable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(ByteBuffer buffer)
|
||||
public void call(Void arg)
|
||||
{
|
||||
fill(buffer);
|
||||
onFillable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ public class CheckReverseProxyHeadersTest
|
|||
try
|
||||
{
|
||||
server.start();
|
||||
connector.getResponses("GET / HTTP/1.1\n" + headers + "\n\n");
|
||||
connector.getResponses("GET / HTTP/1.1\r\n" +"Connection: close\r\n" + headers + "\r\n\r\n");
|
||||
|
||||
Error error = validationHandler.getError();
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public class LocalConnectorTest
|
|||
_connector.getResponses("" +
|
||||
"GET / HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n");
|
||||
|
||||
assertTrue(openLatch.await(5, TimeUnit.SECONDS));
|
||||
|
|
|
@ -612,7 +612,8 @@ public class RequestTest
|
|||
response=_connector.getResponses(
|
||||
"GET / HTTP/1.1\n"+
|
||||
"Host: whatever\n"+
|
||||
"\n"
|
||||
"\n",
|
||||
200, TimeUnit.MILLISECONDS
|
||||
);
|
||||
assertTrue(response.indexOf("200")>0);
|
||||
assertFalse(response.indexOf("Connection: close")>0);
|
||||
|
@ -661,7 +662,8 @@ public class RequestTest
|
|||
"GET / HTTP/1.0\n"+
|
||||
"Host: whatever\n"+
|
||||
"Connection: Other,,keep-alive\n"+
|
||||
"\n"
|
||||
"\n",
|
||||
200, TimeUnit.MILLISECONDS
|
||||
);
|
||||
assertTrue(response.indexOf("200")>0);
|
||||
assertTrue(response.indexOf("Connection: keep-alive")>0);
|
||||
|
@ -682,7 +684,8 @@ public class RequestTest
|
|||
response=_connector.getResponses(
|
||||
"GET / HTTP/1.1\n"+
|
||||
"Host: whatever\n"+
|
||||
"\n"
|
||||
"\n",
|
||||
200, TimeUnit.MILLISECONDS
|
||||
);
|
||||
assertTrue(response.indexOf("200")>0);
|
||||
assertTrue(response.indexOf("Connection: TE,Other")>0);
|
||||
|
|
|
@ -88,7 +88,7 @@ public class ResponseTest
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void send(ResponseInfo info, ByteBuffer content, boolean lastContent, C context, Callback<C> callback)
|
||||
public void send(ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -637,20 +637,6 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest
|
|||
Assert.assertEquals(contextValue, request.getAttribute(contextKey));
|
||||
context.put(contextKey, request.getAttribute(contextKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int read(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context) throws IOException
|
||||
{
|
||||
Assert.assertEquals(contextValue, context.get(contextKey));
|
||||
return super.read(endPoint, buffer, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(EndPoint endPoint, ByteBuffer buffer, ConcurrentMap<String, Object> context, Callback<Void> callback)
|
||||
{
|
||||
Assert.assertEquals(contextValue, context.get(contextKey));
|
||||
super.write(endPoint, buffer, context, callback);
|
||||
}
|
||||
});
|
||||
proxy.start();
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class ContextHandlerCollectionTest
|
|||
try
|
||||
{
|
||||
server.start();
|
||||
connector.getResponses("GET / HTTP/1.1\n" + "Host: www.example.com.\n\n");
|
||||
connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
|
||||
|
||||
assertTrue(handlerA.isHandled());
|
||||
assertFalse(handlerB.isHandled());
|
||||
|
@ -81,7 +81,7 @@ public class ContextHandlerCollectionTest
|
|||
handlerB.reset();
|
||||
handlerC.reset();
|
||||
|
||||
connector.getResponses("GET / HTTP/1.1\n" + "Host: www.example2.com\n\n");
|
||||
connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example2.com\n\n");
|
||||
|
||||
assertFalse(handlerA.isHandled());
|
||||
assertTrue(handlerB.isHandled());
|
||||
|
@ -149,7 +149,7 @@ public class ContextHandlerCollectionTest
|
|||
|
||||
for(String host : requestHosts)
|
||||
{
|
||||
connector.getResponses("GET / HTTP/1.1\n" + "Host: "+host+"\nConnection:close\n\n");
|
||||
connector.getResponses("GET / HTTP/1.0\n" + "Host: "+host+"\nConnection:close\n\n");
|
||||
if(succeed)
|
||||
assertTrue("'"+host+"' should have been handled.",handler.isHandled());
|
||||
else
|
||||
|
|
|
@ -95,7 +95,7 @@ public class ContextHandlerTest
|
|||
try
|
||||
{
|
||||
server.start();
|
||||
connector.getResponses("GET / HTTP/1.1\n" + "Host: www.example.com.\n\n");
|
||||
connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example.com.\n\n");
|
||||
|
||||
assertTrue(handlerA.isHandled());
|
||||
assertFalse(handlerB.isHandled());
|
||||
|
@ -105,7 +105,7 @@ public class ContextHandlerTest
|
|||
handlerB.reset();
|
||||
handlerC.reset();
|
||||
|
||||
connector.getResponses("GET / HTTP/1.1\n" + "Host: www.example2.com\n\n");
|
||||
connector.getResponses("GET / HTTP/1.0\n" + "Host: www.example2.com\n\n");
|
||||
|
||||
assertFalse(handlerA.isHandled());
|
||||
assertTrue(handlerB.isHandled());
|
||||
|
@ -180,7 +180,7 @@ public class ContextHandlerTest
|
|||
assertThat(connector.getResponses("GET /foo/bar/xxx HTTP/1.0\n\n"),Matchers.containsString("ctx='/foo'"));
|
||||
|
||||
// If we shutdown foo then requests will be 503'd
|
||||
foo.shutdown(null).get();
|
||||
foo.shutdown().get();
|
||||
assertThat(connector.getResponses("GET / HTTP/1.0\n\n"),Matchers.containsString("ctx=''"));
|
||||
assertThat(connector.getResponses("GET /foo/xxx HTTP/1.0\n\n"),Matchers.containsString("503"));
|
||||
assertThat(connector.getResponses("GET /foo/bar/xxx HTTP/1.0\n\n"),Matchers.containsString("503"));
|
||||
|
|
|
@ -585,7 +585,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Client Hello
|
||||
TLSRecord record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
proxy.flushToServer(5, b);
|
||||
|
||||
// Server Hello + Certificate + Server Done
|
||||
record = proxy.readFromServer();
|
||||
|
@ -594,17 +594,17 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Client Key Exchange
|
||||
record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
proxy.flushToServer(5,b);
|
||||
|
||||
// Change Cipher Spec
|
||||
record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
proxy.flushToServer(5, b);
|
||||
|
||||
// Client Done
|
||||
record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
proxy.flushToServer(5, b);
|
||||
|
||||
// Change Cipher Spec
|
||||
record = proxy.readFromServer();
|
||||
|
@ -614,7 +614,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
record = proxy.readFromServer();
|
||||
proxy.flushToClient(record);
|
||||
|
||||
Assert.assertNull(handshake.get(5, TimeUnit.SECONDS));
|
||||
Assert.assertNull(handshake.get(1, TimeUnit.SECONDS));
|
||||
|
||||
Future<Object> request = threadPool.submit(new Callable<Object>()
|
||||
{
|
||||
|
@ -634,8 +634,8 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Application data
|
||||
record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
Assert.assertNull(request.get(5, TimeUnit.SECONDS));
|
||||
proxy.flushToServer(5, b);
|
||||
Assert.assertNull(request.get(1, TimeUnit.SECONDS));
|
||||
|
||||
// Application data
|
||||
record = proxy.readFromServer();
|
||||
|
@ -665,7 +665,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
// Close Alert
|
||||
record = proxy.readFromClient();
|
||||
for (byte b : record.getBytes())
|
||||
proxy.flushToServer(50, b);
|
||||
proxy.flushToServer(5, b);
|
||||
// Socket close
|
||||
record = proxy.readFromClient();
|
||||
Assert.assertNull(String.valueOf(record), record);
|
||||
|
|
|
@ -41,9 +41,9 @@ import org.eclipse.jetty.io.SelectorManager;
|
|||
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
|
||||
import org.eclipse.jetty.spdy.FlowControlStrategy;
|
||||
import org.eclipse.jetty.spdy.Promise;
|
||||
import org.eclipse.jetty.spdy.api.Session;
|
||||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
|
@ -316,14 +316,14 @@ public class SPDYClient
|
|||
}
|
||||
catch (RuntimeException x)
|
||||
{
|
||||
sessionPromise.failed(null,x);
|
||||
sessionPromise.failed(x);
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SessionPromise extends Promise<Session>
|
||||
static class SessionPromise extends FuturePromise<Session>
|
||||
{
|
||||
private final SocketChannel channel;
|
||||
final SPDYClient client;
|
||||
|
|
|
@ -52,7 +52,7 @@ public class SPDYClientConnectionFactory
|
|||
StandardSession session = new StandardSession(client.version, bufferPool, factory.getExecutor(), factory.getScheduler(), connection, connection, 1, sessionPromise.listener, generator, flowControlStrategy);
|
||||
session.setWindowSize(client.getInitialWindowSize());
|
||||
parser.addListener(session);
|
||||
sessionPromise.completed(session);
|
||||
sessionPromise.succeeded(session);
|
||||
connection.setSession(session);
|
||||
|
||||
factory.sessionOpened(session);
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.Callback;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
public class SPDYConnection extends AbstractConnection implements Controller<StandardSession.FrameBytes>, IdleListener
|
||||
public class SPDYConnection extends AbstractConnection implements Controller, IdleListener
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(SPDYConnection.class);
|
||||
private final ByteBufferPool bufferPool;
|
||||
|
@ -116,12 +116,10 @@ public class SPDYConnection extends AbstractConnection implements Controller<Sta
|
|||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer buffer, final Callback<StandardSession.FrameBytes> callback, StandardSession.FrameBytes context)
|
||||
public void write(ByteBuffer buffer, final Callback callback)
|
||||
{
|
||||
EndPoint endPoint = getEndPoint();
|
||||
int remaining = buffer.remaining();
|
||||
endPoint.write(context, callback, buffer);
|
||||
return remaining - buffer.remaining();
|
||||
endPoint.write(callback, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,9 +22,9 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
public interface Controller<T>
|
||||
public interface Controller
|
||||
{
|
||||
public int write(ByteBuffer buffer, Callback<T> callback, T context);
|
||||
public void write(ByteBuffer buffer, Callback callback);
|
||||
|
||||
public void close(boolean onlyOutput);
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ public interface ISession extends Session
|
|||
*/
|
||||
public void flush();
|
||||
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback<C> callback, C context);
|
||||
public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback<C> callback, C context);
|
||||
public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Gracefully shuts down this session.</p>
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.spdy;
|
||||
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
|
||||
@Deprecated
|
||||
public class Promise<T> extends FutureCallback<T>
|
||||
{
|
||||
}
|
|
@ -83,7 +83,7 @@ public class SPDYv3FlowControlStrategy implements FlowControlStrategy
|
|||
if (dataInfo.consumed() == length && !stream.isClosed() && length > 0)
|
||||
{
|
||||
WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length);
|
||||
session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, null, null);
|
||||
session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,17 +71,21 @@ import org.eclipse.jetty.util.Atomics;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.ForkInvoker;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.PromisingCallback;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
|
||||
public class StandardSession implements ISession, Parser.Listener, Callback<StandardSession.FrameBytes>, Dumpable
|
||||
public class StandardSession implements ISession, Parser.Listener, Dumpable
|
||||
{
|
||||
private static final Logger logger = Log.getLogger(Session.class);
|
||||
|
||||
private final ForkInvoker<Runnable> invoker = new SessionInvoker();
|
||||
private final ForkInvoker<Callback> invoker = new SessionInvoker();
|
||||
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
|
||||
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
|
||||
private final ConcurrentMap<Integer, IStream> streams = new ConcurrentHashMap<>();
|
||||
|
@ -90,7 +94,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
private final Executor threadPool;
|
||||
private final Scheduler scheduler;
|
||||
private final short version;
|
||||
private final Controller<FrameBytes> controller;
|
||||
private final Controller controller;
|
||||
private final IdleListener idleListener;
|
||||
private final AtomicInteger streamIds;
|
||||
private final AtomicInteger pingIds;
|
||||
|
@ -104,7 +108,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
private Throwable failure;
|
||||
|
||||
public StandardSession(short version, ByteBufferPool bufferPool, Executor threadPool, Scheduler scheduler,
|
||||
Controller<FrameBytes> controller, IdleListener idleListener, int initialStreamId, SessionFrameListener listener,
|
||||
Controller controller, IdleListener idleListener, int initialStreamId, SessionFrameListener listener,
|
||||
Generator generator, FlowControlStrategy flowControlStrategy)
|
||||
{
|
||||
// TODO this should probably be an aggregate lifecycle
|
||||
|
@ -143,13 +147,13 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
@Override
|
||||
public Future<Stream> syn(SynInfo synInfo, StreamFrameListener listener)
|
||||
{
|
||||
Promise<Stream> result = new Promise<>();
|
||||
FuturePromise<Stream> result = new FuturePromise<>();
|
||||
syn(synInfo,listener,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Callback<Stream> callback)
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Promise<Stream> promise)
|
||||
{
|
||||
// Synchronization is necessary.
|
||||
// SPEC v3, 2.3.1 requires that the stream creation be monotonically crescent
|
||||
|
@ -167,7 +171,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
// TODO: for SPDYv3 we need to support the "slot" argument
|
||||
SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders());
|
||||
IStream stream = createStream(synStream, listener, true);
|
||||
generateAndEnqueueControlFrame(stream, synStream, timeout, unit, callback, stream);
|
||||
generateAndEnqueueControlFrame(stream, synStream, timeout, unit, new PromisingCallback<Stream>(promise,stream));
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
@ -175,25 +179,25 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
@Override
|
||||
public Future<Void> rst(RstInfo rstInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
FutureCallback result = new FutureCallback();
|
||||
rst(rstInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
// SPEC v3, 2.2.2
|
||||
if (goAwaySent.get())
|
||||
{
|
||||
complete(callback,null);
|
||||
complete(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
int streamId = rstInfo.getStreamId();
|
||||
IStream stream = streams.get(streamId);
|
||||
RstStreamFrame frame = new RstStreamFrame(version,streamId,rstInfo.getStreamStatus().getCode(version));
|
||||
control(stream,frame,timeout,unit,callback,null);
|
||||
control(stream,frame,timeout,unit,callback);
|
||||
if (stream != null)
|
||||
{
|
||||
stream.process(frame);
|
||||
|
@ -205,33 +209,33 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
@Override
|
||||
public Future<Void> settings(SettingsInfo settingsInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
FutureCallback result = new FutureCallback();
|
||||
settings(settingsInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
SettingsFrame frame = new SettingsFrame(version,settingsInfo.getFlags(),settingsInfo.getSettings());
|
||||
control(null, frame, timeout, unit, callback, null);
|
||||
control(null, frame, timeout, unit, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<PingInfo> ping()
|
||||
{
|
||||
Promise<PingInfo> result = new Promise<>();
|
||||
FuturePromise<PingInfo> result = new FuturePromise<>();
|
||||
ping(0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping(long timeout, TimeUnit unit, Callback<PingInfo> callback)
|
||||
public void ping(long timeout, TimeUnit unit, Promise<PingInfo> promise)
|
||||
{
|
||||
int pingId = pingIds.getAndAdd(2);
|
||||
PingInfo pingInfo = new PingInfo(pingId);
|
||||
PingFrame frame = new PingFrame(version,pingId);
|
||||
control(null,frame,timeout,unit,callback,pingInfo);
|
||||
control(null,frame,timeout,unit,new PromisingCallback<PingInfo>(promise,pingInfo));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -242,29 +246,29 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
|
||||
private Future<Void> goAway(SessionStatus sessionStatus)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
FutureCallback result = new FutureCallback();
|
||||
goAway(sessionStatus, 0, TimeUnit.MILLISECONDS, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goAway(long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
public void goAway(long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
goAway(SessionStatus.OK, timeout, unit, callback);
|
||||
}
|
||||
|
||||
private void goAway(SessionStatus sessionStatus, long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
private void goAway(SessionStatus sessionStatus, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
if (goAwaySent.compareAndSet(false,true))
|
||||
{
|
||||
if (!goAwayReceived.get())
|
||||
{
|
||||
GoAwayFrame frame = new GoAwayFrame(version,lastStreamId.get(),sessionStatus.getCode());
|
||||
control(null,frame,timeout,unit,callback,null);
|
||||
control(null,frame,timeout,unit,callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
complete(callback, null);
|
||||
complete(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -632,7 +636,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
else
|
||||
{
|
||||
control(null, frame, 0, TimeUnit.MILLISECONDS, null, null);
|
||||
control(null, frame, 0, TimeUnit.MILLISECONDS, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,13 +825,13 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
|
||||
|
||||
@Override
|
||||
public <C> void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback<C> callback, C context)
|
||||
public void control(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
generateAndEnqueueControlFrame(stream,frame,timeout,unit,callback,context);
|
||||
generateAndEnqueueControlFrame(stream,frame,timeout,unit,callback);
|
||||
flush();
|
||||
}
|
||||
|
||||
private <C> void generateAndEnqueueControlFrame(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback<C> callback, C context)
|
||||
private void generateAndEnqueueControlFrame(IStream stream, ControlFrame frame, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -838,7 +842,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
{
|
||||
ByteBuffer buffer = generator.control(frame);
|
||||
logger.debug("Queuing {} on {}", frame, stream);
|
||||
ControlFrameBytes<C> frameBytes = new ControlFrameBytes<>(stream, callback, context, frame, buffer);
|
||||
ControlFrameBytes frameBytes = new ControlFrameBytes(stream, callback, frame, buffer);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes, timeout, unit);
|
||||
|
||||
|
@ -851,7 +855,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
notifyCallbackFailed(callback, context, x);
|
||||
notifyCallbackFailed(callback, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -863,10 +867,10 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback<C> callback, C context)
|
||||
public void data(IStream stream, DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
logger.debug("Queuing {} on {}",dataInfo,stream);
|
||||
DataFrameBytes<C> frameBytes = new DataFrameBytes<>(stream,callback,context,dataInfo);
|
||||
DataFrameBytes frameBytes = new DataFrameBytes(stream,callback,dataInfo);
|
||||
if (timeout > 0)
|
||||
frameBytes.task = scheduler.schedule(frameBytes,timeout,unit);
|
||||
append(frameBytes);
|
||||
|
@ -932,7 +936,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
flushing = true;
|
||||
logger.debug("Flushing {}, {} frame(s) in queue",frameBytes,queue.size());
|
||||
}
|
||||
write(buffer,this,frameBytes);
|
||||
write(buffer,new SessionWrite(frameBytes));
|
||||
}
|
||||
|
||||
private void append(FrameBytes frameBytes)
|
||||
|
@ -983,87 +987,73 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
frameBytes.fail(new SPDYException(failure));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed(FrameBytes frameBytes)
|
||||
private class SessionWrite implements Callback
|
||||
{
|
||||
synchronized (queue)
|
||||
final FrameBytes frameBytes;
|
||||
SessionWrite(FrameBytes frameBytes)
|
||||
{
|
||||
logger.debug("Completed write of {}, {} frame(s) in queue",frameBytes,queue.size());
|
||||
flushing = false;
|
||||
}
|
||||
frameBytes.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(FrameBytes frameBytes, Throwable x)
|
||||
{
|
||||
List<FrameBytes> frameBytesToFail = new ArrayList<>();
|
||||
frameBytesToFail.add(frameBytes);
|
||||
|
||||
synchronized (queue)
|
||||
{
|
||||
failure = x;
|
||||
String logMessage = String.format("Failed write of %s, failing all %d frame(s) in queue",frameBytes,queue.size());
|
||||
logger.debug(logMessage,x);
|
||||
frameBytesToFail.addAll(queue);
|
||||
queue.clear();
|
||||
flushing = false;
|
||||
this.frameBytes=frameBytes;
|
||||
}
|
||||
|
||||
for (FrameBytes fb : frameBytesToFail)
|
||||
fb.fail(x);
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
synchronized (queue)
|
||||
{
|
||||
logger.debug("Completed write of {}, {} frame(s) in queue",frameBytes,queue.size());
|
||||
flushing = false;
|
||||
}
|
||||
frameBytes.complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
// TODO because this is using frameBytes here, then it is not really a Promise.
|
||||
// frameBytes is not a result, but is something known before the operation is attempted!
|
||||
|
||||
List<FrameBytes> frameBytesToFail = new ArrayList<>();
|
||||
frameBytesToFail.add(frameBytes);
|
||||
|
||||
synchronized (queue)
|
||||
{
|
||||
failure = x;
|
||||
String logMessage = String.format("Failed write of %s, failing all %d frame(s) in queue",frameBytes,queue.size());
|
||||
logger.debug(logMessage,x);
|
||||
frameBytesToFail.addAll(queue);
|
||||
queue.clear();
|
||||
flushing = false;
|
||||
}
|
||||
|
||||
for (FrameBytes fb : frameBytesToFail)
|
||||
fb.fail(x);
|
||||
}
|
||||
}
|
||||
|
||||
protected void write(ByteBuffer buffer, Callback<FrameBytes> callback, FrameBytes frameBytes)
|
||||
protected void write(ByteBuffer buffer, Callback callback)
|
||||
{
|
||||
if (controller != null)
|
||||
{
|
||||
logger.debug("Writing {} frame bytes of {}",buffer.remaining(),frameBytes);
|
||||
controller.write(buffer,callback,frameBytes);
|
||||
logger.debug("Writing {} frame bytes of {}",buffer.remaining());
|
||||
controller.write(buffer,callback);
|
||||
}
|
||||
}
|
||||
|
||||
private <C> void complete(final Callback<C> callback, final C context)
|
||||
private void complete(final Callback callback)
|
||||
{
|
||||
// Applications may send and queue up a lot of frames and
|
||||
// if we call Callback.completed() only synchronously we risk
|
||||
// starvation (for the last frames sent) and stack overflow.
|
||||
// Therefore every some invocation, we dispatch to a new thread
|
||||
invoker.invoke(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (callback != null)
|
||||
notifyCallbackCompleted(callback, context);
|
||||
flush();
|
||||
}
|
||||
});
|
||||
invoker.invoke(callback);
|
||||
}
|
||||
|
||||
private <C> void notifyCallbackCompleted(Callback<C> callback, C context)
|
||||
{
|
||||
try
|
||||
{
|
||||
callback.completed(context);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
logger.info("Exception while notifying callback " + callback, x);
|
||||
}
|
||||
catch (Error x)
|
||||
{
|
||||
logger.info("Exception while notifying callback " + callback, x);
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
|
||||
private <C> void notifyCallbackFailed(Callback<C> callback, C context, Throwable x)
|
||||
private void notifyCallbackFailed(Callback callback, Throwable x)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (callback != null)
|
||||
callback.failed(context, x);
|
||||
callback.failed(x);
|
||||
}
|
||||
catch (Exception xx)
|
||||
{
|
||||
|
@ -1086,6 +1076,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
flowControlStrategy.setWindowSize(this, initialWindowSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{v%d,queuSize=%d,windowSize=%d,streams=%d}", getClass().getSimpleName(), hashCode(), version, queue.size(), getWindowSize(), streams.size());
|
||||
|
@ -1104,7 +1095,7 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
ContainerLifeCycle.dump(out,indent,Collections.singletonList(controller),streams.values());
|
||||
}
|
||||
|
||||
private class SessionInvoker extends ForkInvoker<Runnable>
|
||||
private class SessionInvoker extends ForkInvoker<Callback>
|
||||
{
|
||||
private SessionInvoker()
|
||||
{
|
||||
|
@ -1112,15 +1103,20 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
|
||||
@Override
|
||||
public void fork(Runnable task)
|
||||
public void fork(final Callback callback)
|
||||
{
|
||||
execute(task);
|
||||
execute(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run() { callback.succeeded() ; }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(Runnable task)
|
||||
public void call(Callback callback)
|
||||
{
|
||||
task.run();
|
||||
callback.succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1135,18 +1131,18 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
public abstract void fail(Throwable throwable);
|
||||
}
|
||||
|
||||
private abstract class AbstractFrameBytes<C> implements FrameBytes, Runnable
|
||||
private abstract class AbstractFrameBytes implements FrameBytes, Runnable
|
||||
{
|
||||
private final IStream stream;
|
||||
private final Callback<C> callback;
|
||||
private final C context;
|
||||
private final Callback callback;
|
||||
protected volatile Scheduler.Task task;
|
||||
|
||||
protected AbstractFrameBytes(IStream stream, Callback<C> callback, C context)
|
||||
protected AbstractFrameBytes(IStream stream, Callback callback)
|
||||
{
|
||||
if (callback==null)
|
||||
throw new IllegalStateException();
|
||||
this.stream = stream;
|
||||
this.callback = callback;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1174,14 +1170,14 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
public void complete()
|
||||
{
|
||||
cancelTask();
|
||||
StandardSession.this.complete(callback,context);
|
||||
StandardSession.this.complete(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(Throwable x)
|
||||
{
|
||||
cancelTask();
|
||||
notifyCallbackFailed(callback, context, x);
|
||||
notifyCallbackFailed(callback, x);
|
||||
StandardSession.this.flush();
|
||||
}
|
||||
|
||||
|
@ -1200,14 +1196,14 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
}
|
||||
|
||||
private class ControlFrameBytes<C> extends AbstractFrameBytes<C>
|
||||
private class ControlFrameBytes extends AbstractFrameBytes
|
||||
{
|
||||
private final ControlFrame frame;
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
private ControlFrameBytes(IStream stream, Callback<C> callback, C context, ControlFrame frame, ByteBuffer buffer)
|
||||
private ControlFrameBytes(IStream stream, Callback callback, ControlFrame frame, ByteBuffer buffer)
|
||||
{
|
||||
super(stream,callback,context);
|
||||
super(stream,callback);
|
||||
this.frame = frame;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
@ -1243,15 +1239,15 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
}
|
||||
|
||||
private class DataFrameBytes<C> extends AbstractFrameBytes<C>
|
||||
private class DataFrameBytes extends AbstractFrameBytes
|
||||
{
|
||||
private final DataInfo dataInfo;
|
||||
private int size;
|
||||
private volatile ByteBuffer buffer;
|
||||
|
||||
private DataFrameBytes(IStream stream, Callback<C> handler, C context, DataInfo dataInfo)
|
||||
private DataFrameBytes(IStream stream, Callback handler, DataInfo dataInfo)
|
||||
{
|
||||
super(stream,handler,context);
|
||||
super(stream,handler);
|
||||
this.dataInfo = dataInfo;
|
||||
}
|
||||
|
||||
|
@ -1309,11 +1305,11 @@ public class StandardSession implements ISession, Parser.Listener, Callback<Stan
|
|||
}
|
||||
}
|
||||
|
||||
private class CloseFrameBytes extends AbstractFrameBytes<Void>
|
||||
private class CloseFrameBytes extends AbstractFrameBytes
|
||||
{
|
||||
private CloseFrameBytes()
|
||||
{
|
||||
super(null, new Empty<Void>(), null);
|
||||
super(null, new Callback.Adapter());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,6 +39,8 @@ import org.eclipse.jetty.spdy.frames.HeadersFrame;
|
|||
import org.eclipse.jetty.spdy.frames.SynReplyFrame;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -319,17 +321,17 @@ public class StandardStream implements IStream
|
|||
@Override
|
||||
public Future<Stream> syn(SynInfo synInfo)
|
||||
{
|
||||
Promise<Stream> result = new Promise<>();
|
||||
FuturePromise<Stream> result = new FuturePromise<>();
|
||||
syn(synInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Callback<Stream> callback)
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> callback)
|
||||
{
|
||||
if (isClosed() || isReset())
|
||||
{
|
||||
callback.failed(this, new StreamException(getId(), StreamStatus.STREAM_ALREADY_CLOSED,
|
||||
callback.failed(new StreamException(getId(), StreamStatus.STREAM_ALREADY_CLOSED,
|
||||
"Stream: " + this + " already closed or reset!"));
|
||||
return;
|
||||
}
|
||||
|
@ -340,32 +342,32 @@ public class StandardStream implements IStream
|
|||
@Override
|
||||
public Future<Void> reply(ReplyInfo replyInfo)
|
||||
{
|
||||
Promise<Void> result = new Promise<>();
|
||||
FutureCallback result = new FutureCallback();
|
||||
reply(replyInfo,0,TimeUnit.MILLISECONDS,result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
if (isUnidirectional())
|
||||
throw new IllegalStateException("Protocol violation: cannot send SYN_REPLY frames in unidirectional streams");
|
||||
openState = OpenState.REPLY_SENT;
|
||||
updateCloseState(replyInfo.isClose(), true);
|
||||
SynReplyFrame frame = new SynReplyFrame(session.getVersion(), replyInfo.getFlags(), getId(), replyInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, callback, null);
|
||||
session.control(this, frame, timeout, unit, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> data(DataInfo dataInfo)
|
||||
{
|
||||
FutureCallback<Void> fcb = new FutureCallback<>();
|
||||
data(dataInfo,0,TimeUnit.MILLISECONDS,null,fcb);
|
||||
FutureCallback fcb = new FutureCallback();
|
||||
data(dataInfo,0,TimeUnit.MILLISECONDS,fcb);
|
||||
return fcb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C> void data(DataInfo dataInfo, long timeout, TimeUnit unit, C context, Callback<C> callback)
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
if (!canSend())
|
||||
{
|
||||
|
@ -380,19 +382,19 @@ public class StandardStream implements IStream
|
|||
|
||||
// Cannot update the close state here, because the data that we send may
|
||||
// be flow controlled, so we need the stream to update the window size.
|
||||
session.data(this, dataInfo, timeout, unit, callback, context);
|
||||
session.data(this, dataInfo, timeout, unit, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<Void> headers(HeadersInfo headersInfo)
|
||||
{
|
||||
FutureCallback<Void> fcb = new FutureCallback<>();
|
||||
FutureCallback fcb = new FutureCallback();
|
||||
headers(headersInfo,0,TimeUnit.MILLISECONDS,fcb);
|
||||
return fcb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback<Void> callback)
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback callback)
|
||||
{
|
||||
if (!canSend())
|
||||
{
|
||||
|
@ -407,7 +409,7 @@ public class StandardStream implements IStream
|
|||
|
||||
updateCloseState(headersInfo.isClose(), true);
|
||||
HeadersFrame frame = new HeadersFrame(session.getVersion(), headersInfo.getFlags(), getId(), headersInfo.getHeaders());
|
||||
session.control(this, frame, timeout, unit, callback, null);
|
||||
session.control(this, frame, timeout, unit, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* <p>A {@link Session} represents the client-side endpoint of a SPDY connection to a single origin server.</p>
|
||||
|
@ -92,7 +93,7 @@ public interface Session
|
|||
* @param callback the completion callback that gets notified of stream creation
|
||||
* @see #syn(SynInfo, StreamFrameListener)
|
||||
*/
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Callback<Stream> callback);
|
||||
public void syn(SynInfo synInfo, StreamFrameListener listener, long timeout, TimeUnit unit, Promise<Stream> callback);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -116,7 +117,7 @@ public interface Session
|
|||
* @param callback the completion callback that gets notified of reset's send
|
||||
* @see #rst(RstInfo)
|
||||
*/
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback<Void> callback);
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SETTINGS to configure the SPDY connection.</p>
|
||||
|
@ -139,7 +140,7 @@ public interface Session
|
|||
* @param callback the completion callback that gets notified of settings' send
|
||||
* @see #settings(SettingsInfo)
|
||||
*/
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback<Void> callback);
|
||||
public void settings(SettingsInfo settingsInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a PING, normally to measure round-trip time.</p>
|
||||
|
@ -160,7 +161,7 @@ public interface Session
|
|||
* @param callback the completion callback that gets notified of ping's send
|
||||
* @see #ping()
|
||||
*/
|
||||
public void ping(long timeout, TimeUnit unit, Callback<PingInfo> callback);
|
||||
public void ping(long timeout, TimeUnit unit, Promise<PingInfo> callback);
|
||||
|
||||
/**
|
||||
* <p>Closes gracefully this session, sending a GO_AWAY frame and then closing the TCP connection.</p>
|
||||
|
@ -181,7 +182,7 @@ public interface Session
|
|||
* @param callback the completion callback that gets notified of go away's send
|
||||
* @see #goAway()
|
||||
*/
|
||||
public void goAway(long timeout, TimeUnit unit, Callback<Void> callback);
|
||||
public void goAway(long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* @return a snapshot of the streams currently active in this session
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* <p>A {@link Stream} represents a bidirectional exchange of data on top of a {@link Session}.</p>
|
||||
|
@ -111,7 +112,7 @@ public interface Stream
|
|||
* @param callback the completion callback that gets notified once the pushstream is established
|
||||
* @see #syn(SynInfo)
|
||||
*/
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Callback<Stream> callback);
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a SYN_REPLY frame in response to a SYN_STREAM frame.</p>
|
||||
|
@ -135,7 +136,7 @@ public interface Stream
|
|||
* @param callback the completion callback that gets notified of reply sent
|
||||
* @see #reply(ReplyInfo)
|
||||
*/
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback<Void> callback);
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a DATA frame on this stream.</p>
|
||||
|
@ -162,7 +163,7 @@ public interface Stream
|
|||
* @param callback the completion callback that gets notified of data sent
|
||||
* @see #data(DataInfo)
|
||||
*/
|
||||
public <C> void data(DataInfo dataInfo, long timeout, TimeUnit unit, C context, Callback<C> callback);
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>Sends asynchronously a HEADER frame on this stream.</p>
|
||||
|
@ -188,7 +189,7 @@ public interface Stream
|
|||
* @param callback the completion callback that gets notified of headers sent
|
||||
* @see #headers(HeadersInfo)
|
||||
*/
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback<Void> callback);
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback callback);
|
||||
|
||||
/**
|
||||
* @return whether this stream is unidirectional or not
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.jetty.spdy.generator.Generator;
|
|||
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
|
||||
import org.eclipse.jetty.toolchain.test.annotation.Slow;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||
import org.junit.Assert;
|
||||
|
@ -75,15 +76,10 @@ public class AsyncTimeoutTest
|
|||
};
|
||||
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
session.syn(new SynInfo(true), null, timeout, unit, new Callback<Stream>()
|
||||
session.syn(new SynInfo(true), null, timeout, unit, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Stream stream, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failedLatch.countDown();
|
||||
}
|
||||
|
@ -107,14 +103,14 @@ public class AsyncTimeoutTest
|
|||
Session session = new StandardSession(SPDY.V2, bufferPool, threadPool, scheduler, new TestController(), null, 1, null, generator, new FlowControlStrategy.None())
|
||||
{
|
||||
@Override
|
||||
protected void write(ByteBuffer buffer, Callback<FrameBytes> callback, FrameBytes frameBytes)
|
||||
protected void write(ByteBuffer buffer, Callback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Wait if we're writing the data frame (control frame's first byte is 0x80)
|
||||
if (buffer.get(0) == 0)
|
||||
unit.sleep(2 * timeout);
|
||||
super.write(buffer, callback, frameBytes);
|
||||
super.write(buffer, callback);
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
|
@ -125,10 +121,10 @@ public class AsyncTimeoutTest
|
|||
|
||||
Stream stream = session.syn(new SynInfo(false), null).get(5, TimeUnit.SECONDS);
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
stream.data(new StringDataInfo("data", true), timeout, unit, null,new Callback.Empty<Void>()
|
||||
stream.data(new StringDataInfo("data", true), timeout, unit, new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failedLatch.countDown();
|
||||
}
|
||||
|
@ -137,13 +133,12 @@ public class AsyncTimeoutTest
|
|||
Assert.assertTrue(failedLatch.await(2 * timeout, unit));
|
||||
}
|
||||
|
||||
private static class TestController implements Controller<StandardSession.FrameBytes>
|
||||
private static class TestController implements Controller
|
||||
{
|
||||
@Override
|
||||
public int write(ByteBuffer buffer, Callback<StandardSession.FrameBytes> callback, StandardSession.FrameBytes context)
|
||||
public void write(ByteBuffer buffer, Callback callback)
|
||||
{
|
||||
callback.completed(context);
|
||||
return buffer.remaining();
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
|||
import org.eclipse.jetty.spdy.generator.Generator;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.TimerScheduler;
|
||||
import org.junit.After;
|
||||
|
@ -67,12 +68,13 @@ import static org.mockito.Matchers.any;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class StandardSessionTest
|
||||
{
|
||||
@Mock
|
||||
private Controller<FrameBytes> controller;
|
||||
private Controller controller;
|
||||
|
||||
private ByteBufferPool bufferPool;
|
||||
private Executor threadPool;
|
||||
|
@ -102,22 +104,17 @@ public class StandardSessionTest
|
|||
@SuppressWarnings("unchecked")
|
||||
private void setControllerWriteExpectationToFail(final boolean fail)
|
||||
{
|
||||
when(controller.write(any(ByteBuffer.class),any(Callback.class),any(StandardSession.FrameBytes.class))).thenAnswer(new Answer<Integer>()
|
||||
{
|
||||
public Integer answer(InvocationOnMock invocation)
|
||||
{
|
||||
Object[] args = invocation.getArguments();
|
||||
|
||||
Callback<StandardSession.FrameBytes> callback = (Callback<FrameBytes>)args[1];
|
||||
FrameBytes context = (FrameBytes)args[2];
|
||||
|
||||
if (fail)
|
||||
callback.failed(context,new ClosedChannelException());
|
||||
else
|
||||
callback.completed(context);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
doAnswer(new Answer() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
Object[] args = invocation.getArguments();
|
||||
Callback callback = (Callback)args[1];
|
||||
if (fail)
|
||||
callback.failed(new ClosedChannelException());
|
||||
else
|
||||
callback.succeeded();
|
||||
return null;
|
||||
}})
|
||||
.when(controller).write(any(ByteBuffer.class),any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -221,10 +218,10 @@ public class StandardSessionTest
|
|||
{
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
SynInfo synInfo = new SynInfo(headers,false,stream.getPriority());
|
||||
stream.syn(synInfo,5,TimeUnit.SECONDS,new Callback.Empty<Stream>()
|
||||
stream.syn(synInfo,5,TimeUnit.SECONDS,new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Stream stream, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failedLatch.countDown();
|
||||
}
|
||||
|
@ -242,7 +239,7 @@ public class StandardSessionTest
|
|||
assertThatPushStreamIsHalfClosed(pushStream);
|
||||
assertThatPushStreamIsInSession(pushStream);
|
||||
assertThatStreamIsAssociatedWithPushStream(stream,pushStream);
|
||||
session.data(pushStream,new StringDataInfo("close",true),5,TimeUnit.SECONDS,null,null);
|
||||
session.data(pushStream,new StringDataInfo("close",true),5,TimeUnit.SECONDS,null);
|
||||
assertThatPushStreamIsClosed(pushStream);
|
||||
assertThatPushStreamIsNotInSession(pushStream);
|
||||
assertThatStreamIsNotAssociatedWithPushStream(stream,pushStream);
|
||||
|
@ -331,7 +328,7 @@ public class StandardSessionTest
|
|||
session.addListener(new TestStreamListener(createdListenerCalledLatch,closedListenerCalledLatch));
|
||||
IStream stream = createStream();
|
||||
IStream pushStream = createPushStream(stream);
|
||||
session.data(pushStream,new StringDataInfo("close",true),5,TimeUnit.SECONDS,null,null);
|
||||
session.data(pushStream,new StringDataInfo("close",true),5,TimeUnit.SECONDS,null);
|
||||
assertThat("onStreamCreated listener has been called twice. Once for the stream and once for the pushStream",
|
||||
createdListenerCalledLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
assertThatOnStreamClosedListenerHasBeenCalled(closedListenerCalledLatch);
|
||||
|
@ -420,21 +417,21 @@ public class StandardSessionTest
|
|||
SynStreamFrame synStreamFrame = new SynStreamFrame(SPDY.V2, SynInfo.FLAG_CLOSE, 1, 0, (byte)0, (short)0, null);
|
||||
IStream stream = new StandardStream(synStreamFrame.getStreamId(), synStreamFrame.getPriority(), session, null);
|
||||
stream.updateWindowSize(8192);
|
||||
Callback.Empty<Void> callback = new Callback.Empty()
|
||||
Callback.Adapter callback = new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Object context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failedCalledLatch.countDown();
|
||||
}
|
||||
};
|
||||
|
||||
// first data frame should fail on controller.write()
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, null,callback);
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, callback);
|
||||
// second data frame should fail without controller.writer() as the connection is expected to be broken after first controller.write() call failed.
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, null,callback);
|
||||
stream.data(new StringDataInfo("data", false), 5, TimeUnit.SECONDS, callback);
|
||||
|
||||
verify(controller, times(1)).write(any(ByteBuffer.class), any(Callback.class), any(FrameBytes.class));
|
||||
verify(controller, times(1)).write(any(ByteBuffer.class), any(Callback.class));
|
||||
assertThat("Callback.failed has been called twice", failedCalledLatch.await(5, TimeUnit.SECONDS), is(true));
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.spdy.api.StringDataInfo;
|
|||
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||
import org.eclipse.jetty.spdy.frames.SynStreamFrame;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
|
@ -72,7 +73,7 @@ public class StandardStreamTest
|
|||
SynInfo synInfo = new SynInfo(false);
|
||||
when(session.getStreams()).thenReturn(streams);
|
||||
stream.syn(synInfo);
|
||||
verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), synInfo)), any(StreamFrameListener.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(session).syn(argThat(new PushSynInfoMatcher(stream.getId(), synInfo)), any(StreamFrameListener.class), anyLong(), any(TimeUnit.class), any(Promise.class));
|
||||
}
|
||||
|
||||
private class PushSynInfoMatcher extends ArgumentMatcher<PushSynInfo>
|
||||
|
@ -104,10 +105,10 @@ public class StandardStreamTest
|
|||
stream.updateCloseState(true, false);
|
||||
assertThat("stream expected to be closed", stream.isClosed(), is(true));
|
||||
final CountDownLatch failedLatch = new CountDownLatch(1);
|
||||
stream.syn(new SynInfo(false), 1, TimeUnit.SECONDS, new Callback.Empty<Stream>()
|
||||
stream.syn(new SynInfo(false), 1, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Stream stream, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failedLatch.countDown();
|
||||
}
|
||||
|
@ -125,6 +126,6 @@ public class StandardStreamTest
|
|||
stream.updateCloseState(synStreamFrame.isClose(), true);
|
||||
assertThat("stream is half closed", stream.isHalfClosed(), is(true));
|
||||
stream.data(new StringDataInfo("data on half closed stream", true));
|
||||
verify(session, never()).data(any(IStream.class), any(DataInfo.class), anyInt(), any(TimeUnit.class), any(Callback.class), any(void.class));
|
||||
verify(session, never()).data(any(IStream.class), any(DataInfo.class), anyInt(), any(TimeUnit.class), any(Callback.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.eclipse.jetty.spdy.StandardSession;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -87,10 +88,10 @@ public class ClientUsageTest
|
|||
// Then issue another similar request
|
||||
stream.getSession().syn(new SynInfo(true), this);
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
// Differently from JDK 7 AIO, there is no need to
|
||||
// have an explicit parameter for the context since
|
||||
|
@ -142,10 +143,10 @@ public class ClientUsageTest
|
|||
}
|
||||
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new BytesDataInfo("wee".getBytes(Charset.forName("UTF-8")), false));
|
||||
stream.data(new StringDataInfo("foo", false));
|
||||
|
|
|
@ -20,9 +20,12 @@ package org.eclipse.jetty.spdy.api;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -32,7 +35,7 @@ public class ServerUsageTest
|
|||
@Test
|
||||
public void testServerSynAndReplyWithData() throws Exception
|
||||
{
|
||||
new ServerSessionFrameListener.Adapter()
|
||||
ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
|
||||
|
@ -54,12 +57,13 @@ public class ServerUsageTest
|
|||
return null;
|
||||
}
|
||||
};
|
||||
Assert.assertTrue(ssfl!=null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerInitiatesStreamAndPushesData() throws Exception
|
||||
{
|
||||
new ServerSessionFrameListener.Adapter()
|
||||
ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void onConnect(Session session)
|
||||
|
@ -73,10 +77,10 @@ public class ServerUsageTest
|
|||
//
|
||||
// However, the API may allow to initiate the stream
|
||||
|
||||
session.syn(new SynInfo(false), null, 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
session.syn(new SynInfo(false), null, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
// The point here is that we have no idea if the client accepted our stream
|
||||
// So we return a stream, we may be able to send the headers frame, but later
|
||||
|
@ -88,12 +92,13 @@ public class ServerUsageTest
|
|||
});
|
||||
}
|
||||
};
|
||||
Assert.assertTrue(ssfl!=null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerPush() throws Exception
|
||||
{
|
||||
new ServerSessionFrameListener.Adapter()
|
||||
ServerSessionFrameListener ssfl = new ServerSessionFrameListener.Adapter()
|
||||
{
|
||||
@Override
|
||||
public StreamFrameListener onSyn(Stream stream, SynInfo streamInfo)
|
||||
|
@ -103,10 +108,10 @@ public class ServerUsageTest
|
|||
|
||||
Session session = stream.getSession();
|
||||
// Since it's unidirectional, no need to pass the listener
|
||||
session.syn(new SynInfo(new Fields(), false, (byte)0), null, 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
session.syn(new SynInfo(new Fields(), false, (byte)0), null, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream pushStream)
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new StringDataInfo("foo", false));
|
||||
}
|
||||
|
@ -114,5 +119,6 @@ public class ServerUsageTest
|
|||
return null;
|
||||
}
|
||||
};
|
||||
Assert.assertTrue(ssfl!=null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.eclipse.jetty.util.BlockingCallback;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -67,14 +68,14 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, C context, Callback<C> callback)
|
||||
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent, Callback callback)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("send {} {} {} {} last={}%n",this,stream,info,BufferUtil.toDetailString(content),lastContent);
|
||||
|
||||
if (stream.isClosed() || stream.isReset() )
|
||||
{
|
||||
callback.failed(context,new EofException("stream closed"));
|
||||
callback.failed(new EofException("stream closed"));
|
||||
return;
|
||||
}
|
||||
// new Throwable().printStackTrace();
|
||||
|
@ -133,10 +134,10 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
// Is the stream still open?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
// tell the callback about the EOF
|
||||
callback.failed(context,new EofException("stream closed"));
|
||||
callback.failed(new EofException("stream closed"));
|
||||
else
|
||||
// send the data and let it call the callback
|
||||
stream.data(new ByteBufferDataInfo(content, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,context,callback);
|
||||
stream.data(new ByteBufferDataInfo(content, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,callback);
|
||||
}
|
||||
// else do we need to close
|
||||
else if (lastContent)
|
||||
|
@ -144,21 +145,21 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
// Are we closed ?
|
||||
if (stream.isClosed()|| stream.isReset())
|
||||
// already closed by reply, so just tell callback we are complete
|
||||
callback.completed(context);
|
||||
callback.succeeded();
|
||||
else
|
||||
// send empty data to close and let the send call the callback
|
||||
stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,context,callback);
|
||||
stream.data(new ByteBufferDataInfo(BufferUtil.EMPTY_BUFFER, lastContent),endPoint.getIdleTimeout(),TimeUnit.MILLISECONDS,callback);
|
||||
}
|
||||
else
|
||||
// No data and no close so tell callback we are completed
|
||||
callback.completed(context);
|
||||
callback.succeeded();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(HttpGenerator.ResponseInfo info, ByteBuffer content, boolean lastContent) throws IOException
|
||||
{
|
||||
send(info,content,lastContent,streamBlocker.getPhase(),streamBlocker);
|
||||
send(info,content,lastContent,streamBlocker);
|
||||
try
|
||||
{
|
||||
streamBlocker.block();
|
||||
|
@ -201,10 +202,10 @@ public class HttpTransportOverSPDY implements HttpTransport
|
|||
final Fields pushRequestHeaders = createRequestHeaders(scheme, host, uri, pushResource);
|
||||
|
||||
// TODO: handle the timeout better
|
||||
stream.syn(new SynInfo(pushHeaders, false), 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
stream.syn(new SynInfo(pushHeaders, false), 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream pushStream)
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
HttpChannelOverSPDY pushChannel = newHttpChannelOverSPDY(pushStream, pushRequestHeaders);
|
||||
pushChannel.requestStart(pushRequestHeaders, true);
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.eclipse.jetty.spdy.api.SynInfo;
|
|||
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParser.RequestHandler<ByteBuffer>
|
||||
{
|
||||
|
@ -187,17 +188,17 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback<Void> handler)
|
||||
public void rst(RstInfo rstInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
// Not much we can do in HTTP land: just close the connection
|
||||
goAway(timeout, unit, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goAway(long timeout, TimeUnit unit, Callback<Void> handler)
|
||||
public void goAway(long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
getEndPoint().close();
|
||||
handler.completed(null);
|
||||
handler.succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,21 +215,22 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Callback<Stream> handler)
|
||||
public void syn(SynInfo synInfo, long timeout, TimeUnit unit, Promise<Stream> handler)
|
||||
{
|
||||
// TODO is this right? comment or imple are wrong??
|
||||
// HTTP does not support pushed streams
|
||||
handler.completed(new HTTPPushStream(2, getPriority(), getSession(), this));
|
||||
handler.succeeded(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback<Void> handler)
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
// TODO
|
||||
throw new UnsupportedOperationException("Not Yet Implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback<Void> handler)
|
||||
public void reply(ReplyInfo replyInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -263,11 +265,11 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
if (replyInfo.isClose())
|
||||
completed();
|
||||
|
||||
handler.completed(null);
|
||||
handler.succeeded();
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
handler.failed(null, x);
|
||||
handler.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +289,7 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void data(DataInfo dataInfo, long timeout, TimeUnit unit, C context, Callback<C> handler)
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -299,11 +301,11 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
if (dataInfo.isClose())
|
||||
completed();
|
||||
|
||||
handler.completed(context);
|
||||
handler.succeeded();
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
handler.failed(context, x);
|
||||
handler.failed(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,17 +318,17 @@ public class ProxyHTTPSPDYConnection extends HttpConnection implements HttpParse
|
|||
}
|
||||
|
||||
@Override
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback<Void> handler)
|
||||
public void headers(HeadersInfo headersInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
// Ignore pushed headers
|
||||
handler.completed(null);
|
||||
handler.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C> void data(DataInfo dataInfo, long timeout, TimeUnit unit, C context, Callback<C> handler)
|
||||
public void data(DataInfo dataInfo, long timeout, TimeUnit unit, Callback handler)
|
||||
{
|
||||
// Ignore pushed data
|
||||
handler.completed(context);
|
||||
handler.succeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.spdy.client.SPDYClient;
|
|||
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* <p>{@link SPDYProxyEngine} implements a SPDY to SPDY proxy, that is, converts SPDY events received by
|
||||
|
@ -169,7 +170,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
Session existing = serverSessions.putIfAbsent(host, session);
|
||||
if (existing != null)
|
||||
{
|
||||
session.goAway(getTimeout(), TimeUnit.MILLISECONDS, new Callback.Empty<Void>());
|
||||
session.goAway(getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
session = existing;
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +203,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
private void rst(Stream stream)
|
||||
{
|
||||
RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
|
||||
stream.getSession().rst(rstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Empty<Void>());
|
||||
stream.getSession().rst(rstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
}
|
||||
|
||||
private class ProxyStreamFrameListener extends StreamFrameListener.Adapter
|
||||
|
@ -258,16 +259,16 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
{
|
||||
final ReplyInfo replyInfo = this.replyInfo;
|
||||
this.replyInfo = null;
|
||||
clientStream.reply(replyInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback<Void>()
|
||||
clientStream.reply(replyInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
logger.debug("P -> C {} from {} to {}", replyInfo, stream, clientStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
logger.debug(x);
|
||||
rst(clientStream);
|
||||
|
@ -277,17 +278,17 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
|
||||
private void data(final Stream stream, final DataInfo dataInfo)
|
||||
{
|
||||
clientStream.data(dataInfo, getTimeout(), TimeUnit.MILLISECONDS, null,new Callback<Void>()
|
||||
clientStream.data(dataInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
dataInfo.consume(dataInfo.length());
|
||||
logger.debug("P -> C {} from {} to {}", dataInfo, stream, clientStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
logger.debug(x);
|
||||
rst(clientStream);
|
||||
|
@ -304,7 +305,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
* is a fast producer and the server a slow consumer, or if the client is a SPDY v2 client (and hence
|
||||
* without flow control) while the server is a SPDY v3 server (and hence with flow control).</p>
|
||||
*/
|
||||
private class StreamHandler implements Callback<Stream>
|
||||
private class StreamHandler implements Promise<Stream>
|
||||
{
|
||||
private final Queue<DataInfoHandler> queue = new LinkedList<>();
|
||||
private final Stream clientStream;
|
||||
|
@ -318,7 +319,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Stream serverStream)
|
||||
public void succeeded(Stream serverStream)
|
||||
{
|
||||
logger.debug("P -> S {} from {} to {}", serverSynInfo, clientStream, serverStream);
|
||||
|
||||
|
@ -352,7 +353,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(Stream serverStream, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
logger.debug(x);
|
||||
rst(clientStream);
|
||||
|
@ -393,10 +394,10 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
private void flush(Stream serverStream, DataInfoHandler dataInfoHandler)
|
||||
{
|
||||
logger.debug("P -> S {} on {}", dataInfoHandler.dataInfo, serverStream);
|
||||
serverStream.data(dataInfoHandler.dataInfo, getTimeout(), TimeUnit.MILLISECONDS, null,dataInfoHandler);
|
||||
serverStream.data(dataInfoHandler.dataInfo, getTimeout(), TimeUnit.MILLISECONDS,dataInfoHandler);
|
||||
}
|
||||
|
||||
private class DataInfoHandler implements Callback<Void>
|
||||
private class DataInfoHandler implements Callback
|
||||
{
|
||||
private final DataInfo dataInfo;
|
||||
private boolean flushing;
|
||||
|
@ -407,7 +408,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
Stream serverStream;
|
||||
DataInfoHandler dataInfoHandler;
|
||||
|
@ -434,7 +435,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
logger.debug(x);
|
||||
rst(clientStream);
|
||||
|
@ -474,7 +475,7 @@ public class SPDYProxyEngine extends ProxyEngine implements StreamFrameListener
|
|||
{
|
||||
Session clientSession = clientStream.getSession();
|
||||
RstInfo clientRstInfo = new RstInfo(clientStream.getId(), serverRstInfo.getStreamStatus());
|
||||
clientSession.rst(clientRstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Empty<Void>());
|
||||
clientSession.rst(clientRstInfo, getTimeout(), TimeUnit.MILLISECONDS, new Callback.Adapter());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,11 +89,10 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = null;
|
||||
boolean lastContent = true;
|
||||
Object context = null;
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
|
||||
}
|
||||
|
@ -104,11 +103,11 @@ public class HttpTransportOverSPDYTest
|
|||
ByteBuffer content = createRandomByteBuffer();
|
||||
|
||||
boolean lastContent = true;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -118,11 +117,11 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = BufferUtil.EMPTY_BUFFER;
|
||||
boolean lastContent = true;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(0));
|
||||
}
|
||||
|
@ -132,11 +131,10 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = null;
|
||||
boolean lastContent = false;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), anyObject(),
|
||||
any(Callback.class));
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -144,11 +142,11 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = createRandomByteBuffer();
|
||||
boolean lastContent = false;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
|
||||
assertThat("ByteBuffer is empty", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -158,12 +156,11 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = BufferUtil.EMPTY_BUFFER;
|
||||
boolean lastContent = false;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(null, content, lastContent, context, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), anyObject(),
|
||||
any(Callback.class));
|
||||
verify(callback, times(1)).completed(context);
|
||||
httpTransportOverSPDY.send(null, content, lastContent, callback);
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
verify(callback, times(1)).succeeded();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -171,16 +168,16 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = null;
|
||||
boolean lastContent = true;
|
||||
Object context = null;
|
||||
|
||||
// when stream.isClosed() is called a 2nd time, the teply has closed the stream already
|
||||
when(stream.isClosed()).thenReturn(false).thenReturn(true);
|
||||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(true));
|
||||
|
||||
verify(callback, times(1)).completed(context);
|
||||
verify(callback, times(1)).succeeded();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -189,16 +186,16 @@ public class HttpTransportOverSPDYTest
|
|||
ByteBuffer content = createRandomByteBuffer();
|
||||
|
||||
boolean lastContent = true;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is true", dataInfoCaptor.getValue().isClose(), is(true));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
@ -208,15 +205,14 @@ public class HttpTransportOverSPDYTest
|
|||
{
|
||||
ByteBuffer content = null;
|
||||
boolean lastContent = false;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
assertThat("ReplyInfo close is true", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), anyObject(),
|
||||
any(Callback.class));
|
||||
verify(stream, times(0)).data(any(ByteBufferDataInfo.class), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -225,15 +221,15 @@ public class HttpTransportOverSPDYTest
|
|||
ByteBuffer content = createRandomByteBuffer();
|
||||
|
||||
boolean lastContent = false;
|
||||
Object context = null;
|
||||
|
||||
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, context, callback);
|
||||
httpTransportOverSPDY.send(responseInfo, content, lastContent, callback);
|
||||
ArgumentCaptor<ReplyInfo> replyInfoCaptor = ArgumentCaptor.forClass(ReplyInfo.class);
|
||||
verify(stream, times(1)).reply(replyInfoCaptor.capture());
|
||||
assertThat("ReplyInfo close is false", replyInfoCaptor.getValue().isClose(), is(false));
|
||||
|
||||
ArgumentCaptor<ByteBufferDataInfo> dataInfoCaptor = ArgumentCaptor.forClass(ByteBufferDataInfo.class);
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), anyObject(), any(Callback.class));
|
||||
verify(stream, times(1)).data(dataInfoCaptor.capture(), anyLong(), any(TimeUnit.class), any(Callback.class));
|
||||
assertThat("lastContent is false", dataInfoCaptor.getValue().isClose(), is(false));
|
||||
assertThat("ByteBuffer length is 4096", dataInfoCaptor.getValue().length(), is(4096));
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
|||
import org.eclipse.jetty.spdy.server.http.HTTPSPDYHeader;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -564,10 +565,10 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Fields pushHeaders = new Fields();
|
||||
pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Callback.Empty<Stream>()
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream pushStream)
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new BytesDataInfo(data, true));
|
||||
}
|
||||
|
@ -617,10 +618,10 @@ public class ProxyHTTPSPDYTest
|
|||
|
||||
Fields pushHeaders = new Fields();
|
||||
pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Callback.Empty<Stream>()
|
||||
stream.syn(new SynInfo(pushHeaders, false), 5, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream pushStream)
|
||||
public void succeeded(Stream pushStream)
|
||||
{
|
||||
pushStream.data(new BytesDataInfo(data, true));
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.spdy.api.Session;
|
|||
import org.eclipse.jetty.spdy.api.SessionFrameListener;
|
||||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -68,10 +69,10 @@ public class PingTest extends AbstractTest
|
|||
@Override
|
||||
public void onConnect(Session session)
|
||||
{
|
||||
session.ping(0, TimeUnit.MILLISECONDS, new Callback.Empty<PingInfo>()
|
||||
session.ping(0, TimeUnit.MILLISECONDS, new Promise.Adapter<PingInfo>()
|
||||
{
|
||||
@Override
|
||||
public void completed(PingInfo pingInfo)
|
||||
public void succeeded(PingInfo pingInfo)
|
||||
{
|
||||
pingId = pingInfo.getPingId();
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ import org.eclipse.jetty.spdy.parser.Parser;
|
|||
import org.eclipse.jetty.spdy.parser.Parser.Listener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -244,10 +245,10 @@ public class PushStreamTest extends AbstractTest
|
|||
public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
|
||||
{
|
||||
stream.reply(new ReplyInfo(true));
|
||||
stream.syn(new SynInfo(false),1,TimeUnit.SECONDS,new Callback.Empty<Stream>()
|
||||
stream.syn(new SynInfo(false),1,TimeUnit.SECONDS,new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void failed(Stream stream, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
pushStreamFailedLatch.countDown();
|
||||
}
|
||||
|
|
|
@ -134,10 +134,10 @@ public class ResetStreamTest extends AbstractTest
|
|||
});
|
||||
|
||||
Stream stream = session.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
stream.data(new StringDataInfo("data",true),5,TimeUnit.SECONDS,null,new Callback.Empty<Void>()
|
||||
stream.data(new StringDataInfo("data",true),5,TimeUnit.SECONDS,new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
synLatch.countDown();
|
||||
}
|
||||
|
@ -182,12 +182,12 @@ public class ResetStreamTest extends AbstractTest
|
|||
|
||||
Stream stream = session.syn(new SynInfo(false),null).get(5,TimeUnit.SECONDS);
|
||||
assertThat("syn is received by server", synLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
stream.data(new StringDataInfo("data",false),5,TimeUnit.SECONDS,null,null);
|
||||
stream.data(new StringDataInfo("data",false),5,TimeUnit.SECONDS,null);
|
||||
assertThat("stream is reset",rstLatch.await(5,TimeUnit.SECONDS),is(true));
|
||||
stream.data(new StringDataInfo("2nd dataframe",false),5L,TimeUnit.SECONDS,null,new Callback.Empty<Void>()
|
||||
stream.data(new StringDataInfo("2nd dataframe",false),5L,TimeUnit.SECONDS,new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void failed(Void context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
failLatch.countDown();
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.spdy.api.SynInfo;
|
|||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -172,12 +173,12 @@ public class SynDataReplyDataLoadTest extends AbstractTest
|
|||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS, new Callback.Empty<Stream>()
|
||||
}, 0, TimeUnit.SECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new StringDataInfo("data_" + stream.getId(), true), 0, TimeUnit.SECONDS, null,null);
|
||||
stream.data(new StringDataInfo("data_" + stream.getId(), true), 0, TimeUnit.SECONDS, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.eclipse.jetty.spdy.api.SynInfo;
|
|||
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -199,10 +200,10 @@ public class SynReplyTest extends AbstractTest
|
|||
Assert.assertTrue(stream.isHalfClosed());
|
||||
|
||||
stream.reply(new ReplyInfo(false));
|
||||
stream.data(new StringDataInfo(data1, false), 5, TimeUnit.SECONDS, null,new Callback.Empty<Void>()
|
||||
stream.data(new StringDataInfo(data1, false), 5, TimeUnit.SECONDS, new Callback.Adapter()
|
||||
{
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
stream.data(new StringDataInfo(data2, true));
|
||||
}
|
||||
|
@ -278,10 +279,10 @@ public class SynReplyTest extends AbstractTest
|
|||
Assert.assertEquals(clientData, data);
|
||||
clientDataLatch.countDown();
|
||||
}
|
||||
}, 0, TimeUnit.MILLISECONDS, new Callback.Empty<Stream>()
|
||||
}, 0, TimeUnit.MILLISECONDS, new Promise.Adapter<Stream>()
|
||||
{
|
||||
@Override
|
||||
public void completed(Stream stream)
|
||||
public void succeeded(Stream stream)
|
||||
{
|
||||
stream.data(new StringDataInfo(serverData, true));
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.util;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
|
||||
/** Fast B64 Encoder/Decoder as described in RFC 1421.
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
* A Callback for simple reusable conversion of an
|
||||
* asynchronous API to blocking.
|
||||
* <p>
|
||||
* To avoid late redundant calls to {@link #completed(Integer)} or {@link #failed(Integer, Throwable)} from
|
||||
* To avoid late redundant calls to {@link #succeeded()} or {@link #failed(Throwable)} from
|
||||
* interfering with later reuses of this class, the callback context is used to hold pass a phase indicated
|
||||
* and only a single callback per phase is allowed.
|
||||
* <p>
|
||||
|
@ -41,57 +41,45 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
*
|
||||
* public void blockingMethod(Object args) throws Exception
|
||||
* {
|
||||
* asyncMethod(args,cb.getPhase(),cb);
|
||||
* asyncMethod(args,cb);
|
||||
* cb.block();
|
||||
* }
|
||||
*
|
||||
* public <C>void asyncMethod(Object args, C context, Callback<C> callback)
|
||||
* public <C>void asyncMethod(Object args, Callback callback)
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public class BlockingCallback implements Callback<Integer>
|
||||
public class BlockingCallback implements Callback
|
||||
{
|
||||
private static Throwable COMPLETED=new Throwable();
|
||||
private final AtomicBoolean _done=new AtomicBoolean(false);
|
||||
private final Semaphore _semaphone = new Semaphore(0);
|
||||
private Throwable _cause;
|
||||
private volatile int _phase;
|
||||
|
||||
public BlockingCallback()
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void completed(Integer phase)
|
||||
public void succeeded()
|
||||
{
|
||||
if (phase==null)
|
||||
throw new IllegalStateException("Context must be getPhase()");
|
||||
if (_phase==phase.intValue() && _done.compareAndSet(false,true))
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_phase++;
|
||||
_cause=COMPLETED;
|
||||
_semaphone.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Integer phase, Throwable cause)
|
||||
public void failed(Throwable cause)
|
||||
{
|
||||
if (phase==null)
|
||||
throw new IllegalStateException("Context must be getPhase()");
|
||||
if (_phase==phase.intValue() && _done.compareAndSet(false,true))
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_phase++;
|
||||
_cause=cause;
|
||||
_semaphone.release();
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getPhase()
|
||||
{
|
||||
return new Integer(_phase);
|
||||
}
|
||||
|
||||
/** Block until the FutureCallback is done or cancelled and
|
||||
* after the return leave in the state as if a {@link #reset()} had been
|
||||
|
|
|
@ -39,42 +39,42 @@ import org.eclipse.jetty.util.log.Log;
|
|||
/**
|
||||
* <p>A callback abstraction that handles completed/failed events of asynchronous operations.</p>
|
||||
*
|
||||
* <p>Semantically this is equivalent to an optimise Promise<Void>, but callback is a more meaningful
|
||||
* name than EmptyPromise</p>
|
||||
*
|
||||
* @param <C> the type of the context object
|
||||
*/
|
||||
public interface Callback<C>
|
||||
public interface Callback
|
||||
{
|
||||
/**
|
||||
* <p>Callback invoked when the operation completes.</p>
|
||||
*
|
||||
* @param context the context
|
||||
* @see #failed(Object, Throwable)
|
||||
* @see #failed(Throwable)
|
||||
*/
|
||||
public abstract void completed(C context);
|
||||
public abstract void succeeded();
|
||||
|
||||
/**
|
||||
* <p>Callback invoked when the operation fails.</p>
|
||||
*
|
||||
* @param context the context
|
||||
* @param x the reason for the operation failure
|
||||
*/
|
||||
public void failed(C context, Throwable x);
|
||||
public void failed(Throwable x);
|
||||
|
||||
/**
|
||||
* <p>Empty implementation of {@link Callback}</p>
|
||||
*
|
||||
* @param <C> the type of the context object
|
||||
*/
|
||||
public static class Empty<C> implements Callback<C>
|
||||
public static class Adapter implements Callback
|
||||
{
|
||||
@Override
|
||||
public void completed(C context)
|
||||
public void succeeded()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(C context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
Log.getLogger(this.getClass()).warn(String.valueOf(context),x);
|
||||
Log.getLogger(this.getClass()).warn(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,16 @@ package org.eclipse.jetty.util;
|
|||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public abstract class ExecutorCallback<C> implements Callback<C>
|
||||
public abstract class ExecutorCallback implements Callback
|
||||
{
|
||||
private final ForkInvoker<C> _invoker;
|
||||
private final ForkInvoker<Void> _invoker;
|
||||
private final Executor _executor;
|
||||
private final Runnable _onComplete=new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
onCompleted(null);
|
||||
onCompleted();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,39 +47,27 @@ public abstract class ExecutorCallback<C> implements Callback<C>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(final C context)
|
||||
public void succeeded()
|
||||
{
|
||||
// Should we execute?
|
||||
if (_invoker==null)
|
||||
{
|
||||
if (context==null)
|
||||
_executor.execute(_onComplete);
|
||||
else
|
||||
{
|
||||
_executor.execute(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
onCompleted(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
_executor.execute(_onComplete);
|
||||
}
|
||||
else if (alwaysDispatchCompletion())
|
||||
{
|
||||
_invoker.fork(context);
|
||||
_invoker.fork(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_invoker.invoke(context);
|
||||
_invoker.invoke(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void onCompleted(C context);
|
||||
protected abstract void onCompleted();
|
||||
|
||||
@Override
|
||||
public void failed(final C context, final Throwable x)
|
||||
public void failed(final Throwable x)
|
||||
{
|
||||
// Always execute failure
|
||||
Runnable runnable = new Runnable()
|
||||
|
@ -87,13 +75,13 @@ public abstract class ExecutorCallback<C> implements Callback<C>
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
onFailed(context, x);
|
||||
onFailed(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ExecutorCallback@%x{%s,%s}", hashCode(), context, x);
|
||||
return String.format("ExecutorCallback@%x{%s}", hashCode(), x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -103,7 +91,7 @@ public abstract class ExecutorCallback<C> implements Callback<C>
|
|||
_executor.execute(runnable);
|
||||
}
|
||||
|
||||
protected void onFailed(C context, Throwable x)
|
||||
protected void onFailed(Throwable x)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -118,7 +106,7 @@ public abstract class ExecutorCallback<C> implements Callback<C>
|
|||
return String.format("%s@%x", getClass(), hashCode());
|
||||
}
|
||||
|
||||
private class ExecutorCallbackInvoker extends ForkInvoker<C> implements Runnable
|
||||
private class ExecutorCallbackInvoker extends ForkInvoker<Void> implements Runnable
|
||||
{
|
||||
private ExecutorCallbackInvoker(int maxInvocations)
|
||||
{
|
||||
|
@ -126,34 +114,21 @@ public abstract class ExecutorCallback<C> implements Callback<C>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void fork(final C context)
|
||||
public void fork(Void arg)
|
||||
{
|
||||
_executor.execute(context == null ? this : new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
call(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ExecutorCallback@%x{%s}", hashCode(), context);
|
||||
}
|
||||
});
|
||||
_executor.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(C context)
|
||||
public void call(Void arg)
|
||||
{
|
||||
onCompleted(context);
|
||||
onCompleted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
call(null);
|
||||
onCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
package org.eclipse.jetty.util;
|
||||
|
||||
/**
|
||||
* Utility class that splits calls to {@link #invoke(T)} into calls to {@link #fork(T)} or {@link #call(T)}
|
||||
* depending on the max number of reentrant calls to {@link #invoke(T)}.
|
||||
* Utility class that splits calls to {@link #invoke(Object)} into calls to {@link #fork(Object)} or {@link #call(Object)}
|
||||
* depending on the max number of reentrant calls to {@link #invoke(Object)}.
|
||||
* <p/>
|
||||
* This class prevents {@link StackOverflowError}s in case of methods that end up invoking themselves,
|
||||
* such is common for {@link Callback#completed(Object)}.
|
||||
* such is common for {@link Callback#succeeded()}.
|
||||
* <p/>
|
||||
* Typical use case is:
|
||||
* <pre>
|
||||
|
@ -48,7 +48,6 @@ package org.eclipse.jetty.util;
|
|||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> the generic type of this class
|
||||
*/
|
||||
public abstract class ForkInvoker<T>
|
||||
{
|
||||
|
@ -63,12 +62,12 @@ public abstract class ForkInvoker<T>
|
|||
private final int _maxInvocations;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given max number of reentrant calls to {@link #invoke(T)}
|
||||
* Creates an instance with the given max number of reentrant calls to {@link #invoke(Object)}
|
||||
* <p/>
|
||||
* If {@code maxInvocations} is zero or negative, it is interpreted
|
||||
* as if the max number of reentrant calls is infinite.
|
||||
*
|
||||
* @param maxInvocations the max number of reentrant calls to {@link #invoke(T)}
|
||||
* @param maxInvocations the max number of reentrant calls to {@link #invoke(Object)}
|
||||
*/
|
||||
public ForkInvoker(int maxInvocations)
|
||||
{
|
||||
|
@ -76,22 +75,22 @@ public abstract class ForkInvoker<T>
|
|||
}
|
||||
|
||||
/**
|
||||
* Invokes either {@link #fork(T)} or {@link #call(T)}.
|
||||
* If {@link #condition()} returns true, {@link #fork(T)} is invoked.
|
||||
* Invokes either {@link #fork(Object)} or {@link #call(Object)}.
|
||||
* If {@link #condition()} returns true, {@link #fork(Object)} is invoked.
|
||||
* Otherwise, if the max number of reentrant calls is positive and the
|
||||
* actual number of reentrant invocations exceeds it, {@link #fork(T)} is invoked.
|
||||
* Otherwise, {@link #call(T)} is invoked.
|
||||
* actual number of reentrant invocations exceeds it, {@link #fork(Object)} is invoked.
|
||||
* Otherwise, {@link #call(Object)} is invoked.
|
||||
* @param arg TODO
|
||||
*
|
||||
* @param context the invocation context
|
||||
* @return true if {@link #fork(T)} has been called, false otherwise
|
||||
* @return true if {@link #fork(Object)} has been called, false otherwise
|
||||
*/
|
||||
public boolean invoke(T context)
|
||||
public boolean invoke(T arg)
|
||||
{
|
||||
boolean countInvocations = _maxInvocations > 0;
|
||||
int invocations = __invocations.get();
|
||||
if (condition() || countInvocations && invocations > _maxInvocations)
|
||||
{
|
||||
fork(context);
|
||||
fork(arg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -100,7 +99,7 @@ public abstract class ForkInvoker<T>
|
|||
__invocations.set(invocations + 1);
|
||||
try
|
||||
{
|
||||
call(context);
|
||||
call(arg);
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
|
@ -113,9 +112,9 @@ public abstract class ForkInvoker<T>
|
|||
|
||||
/**
|
||||
* Subclasses should override this method returning true if they want
|
||||
* {@link #invoke(T)} to call {@link #fork(T)}.
|
||||
* {@link #invoke(Object)} to call {@link #fork(Object)}.
|
||||
*
|
||||
* @return true if {@link #invoke(T)} should call {@link #fork(T)}, false otherwise
|
||||
* @return true if {@link #invoke(Object)} should call {@link #fork(Object)}, false otherwise
|
||||
*/
|
||||
protected boolean condition()
|
||||
{
|
||||
|
@ -124,15 +123,13 @@ public abstract class ForkInvoker<T>
|
|||
|
||||
/**
|
||||
* Executes the forked invocation
|
||||
*
|
||||
* @param context the invocation context
|
||||
* @param arg TODO
|
||||
*/
|
||||
public abstract void fork(T context);
|
||||
public abstract void fork(T arg);
|
||||
|
||||
/**
|
||||
* Executes the direct, non-forked, invocation
|
||||
*
|
||||
* @param context the invocation context
|
||||
* @param arg TODO
|
||||
*/
|
||||
public abstract void call(T context);
|
||||
public abstract void call(T arg);
|
||||
}
|
||||
|
|
|
@ -23,57 +23,52 @@ import java.util.concurrent.CancellationException;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.management.RuntimeErrorException;
|
||||
|
||||
public class FutureCallback<C> implements Future<C>,Callback<C>
|
||||
public class FutureCallback implements Future<Void>,Callback
|
||||
{
|
||||
private static Throwable COMPLETED=new Throwable();
|
||||
private final AtomicBoolean _done=new AtomicBoolean(false);
|
||||
private final CountDownLatch _latch=new CountDownLatch(1);
|
||||
private Throwable _cause;
|
||||
private C _context;
|
||||
|
||||
public FutureCallback()
|
||||
{}
|
||||
|
||||
public FutureCallback(C ctx)
|
||||
public FutureCallback(boolean completed)
|
||||
{
|
||||
_cause=COMPLETED;
|
||||
_context=ctx;
|
||||
_done.set(true);
|
||||
_latch.countDown();
|
||||
if (completed)
|
||||
{
|
||||
_cause=COMPLETED;
|
||||
_done.set(true);
|
||||
_latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
public FutureCallback(C ctx, Throwable failed)
|
||||
public FutureCallback(Throwable failed)
|
||||
{
|
||||
_context=ctx;
|
||||
_cause=failed;
|
||||
_done.set(true);
|
||||
_latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed(C context)
|
||||
public void succeeded()
|
||||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_context=context;
|
||||
_cause=COMPLETED;
|
||||
_latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(C context, Throwable cause)
|
||||
public void failed(Throwable cause)
|
||||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_context=context;
|
||||
_cause=cause;
|
||||
_latch.countDown();
|
||||
}
|
||||
|
@ -84,7 +79,6 @@ public class FutureCallback<C> implements Future<C>,Callback<C>
|
|||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_context=null;
|
||||
_cause=new CancellationException();
|
||||
_latch.countDown();
|
||||
return true;
|
||||
|
@ -117,24 +111,24 @@ public class FutureCallback<C> implements Future<C>,Callback<C>
|
|||
}
|
||||
|
||||
@Override
|
||||
public C get() throws InterruptedException, ExecutionException
|
||||
public Void get() throws InterruptedException, ExecutionException
|
||||
{
|
||||
_latch.await();
|
||||
if (_cause==COMPLETED)
|
||||
return _context;
|
||||
return null;
|
||||
if (_cause instanceof CancellationException)
|
||||
throw (CancellationException) new CancellationException().initCause(_cause);
|
||||
throw new ExecutionException(_cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public C get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
if (!_latch.await(timeout,unit))
|
||||
throw new TimeoutException();
|
||||
|
||||
if (_cause==COMPLETED)
|
||||
return _context;
|
||||
return null;
|
||||
if (_cause instanceof TimeoutException)
|
||||
throw (TimeoutException)_cause;
|
||||
if (_cause instanceof CancellationException)
|
||||
|
@ -157,7 +151,7 @@ public class FutureCallback<C> implements Future<C>,Callback<C>
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("FutureCallback@%x{%b,%b,%s}",hashCode(),_done,_cause==COMPLETED,_context);
|
||||
return String.format("FutureCallback@%x{%b,%b}",hashCode(),_done,_cause==COMPLETED);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class FuturePromise<C> implements Future<C>,Promise<C>
|
||||
{
|
||||
private static Throwable COMPLETED=new Throwable();
|
||||
private final AtomicBoolean _done=new AtomicBoolean(false);
|
||||
private final CountDownLatch _latch=new CountDownLatch(1);
|
||||
private Throwable _cause;
|
||||
private C _result;
|
||||
|
||||
public FuturePromise()
|
||||
{}
|
||||
|
||||
public FuturePromise(C result)
|
||||
{
|
||||
_cause=COMPLETED;
|
||||
_result=result;
|
||||
_done.set(true);
|
||||
_latch.countDown();
|
||||
}
|
||||
|
||||
public FuturePromise(C ctx, Throwable failed)
|
||||
{
|
||||
_result=ctx;
|
||||
_cause=failed;
|
||||
_done.set(true);
|
||||
_latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded(C result)
|
||||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_result=result;
|
||||
_cause=COMPLETED;
|
||||
_latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable cause)
|
||||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_cause=cause;
|
||||
_latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning)
|
||||
{
|
||||
if (_done.compareAndSet(false,true))
|
||||
{
|
||||
_result=null;
|
||||
_cause=new CancellationException();
|
||||
_latch.countDown();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled()
|
||||
{
|
||||
if (_done.get())
|
||||
{
|
||||
try
|
||||
{
|
||||
_latch.await();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return _cause instanceof CancellationException;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone()
|
||||
{
|
||||
return _done.get() && _latch.getCount()==0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public C get() throws InterruptedException, ExecutionException
|
||||
{
|
||||
_latch.await();
|
||||
if (_cause==COMPLETED)
|
||||
return _result;
|
||||
if (_cause instanceof CancellationException)
|
||||
throw (CancellationException) new CancellationException().initCause(_cause);
|
||||
throw new ExecutionException(_cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public C get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
||||
{
|
||||
if (!_latch.await(timeout,unit))
|
||||
throw new TimeoutException();
|
||||
|
||||
if (_cause==COMPLETED)
|
||||
return _result;
|
||||
if (_cause instanceof TimeoutException)
|
||||
throw (TimeoutException)_cause;
|
||||
if (_cause instanceof CancellationException)
|
||||
throw (CancellationException) new CancellationException().initCause(_cause);
|
||||
throw new ExecutionException(_cause);
|
||||
}
|
||||
|
||||
public static void rethrow(ExecutionException e) throws IOException
|
||||
{
|
||||
Throwable cause=e.getCause();
|
||||
if (cause instanceof IOException)
|
||||
throw (IOException)cause;
|
||||
if (cause instanceof Error)
|
||||
throw (Error)cause;
|
||||
if (cause instanceof RuntimeException)
|
||||
throw (RuntimeException)cause;
|
||||
throw new RuntimeException(cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("FutureCallback@%x{%b,%b,%s}",hashCode(),_done,_cause==COMPLETED,_result);
|
||||
}
|
||||
|
||||
}
|
|
@ -35,8 +35,6 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
import javax.servlet.ServletException;
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/**
|
||||
* <p>A callback abstraction that handles completed/failed events of asynchronous operations.</p>
|
||||
*
|
||||
* @param <C> the type of the context object
|
||||
*/
|
||||
public interface Promise<C>
|
||||
{
|
||||
/**
|
||||
* <p>Callback invoked when the operation completes.</p>
|
||||
*
|
||||
* @param result the context
|
||||
* @see #failed(Throwable)
|
||||
*/
|
||||
public abstract void succeeded(C result);
|
||||
|
||||
/**
|
||||
* <p>Callback invoked when the operation fails.</p>
|
||||
*
|
||||
* @param x the reason for the operation failure
|
||||
*/
|
||||
public void failed(Throwable x);
|
||||
|
||||
|
||||
/**
|
||||
* <p>Empty implementation of {@link Promise}</p>
|
||||
*
|
||||
* @param <C> the type of the context object
|
||||
*/
|
||||
public static class Adapter<C> implements Promise<C>
|
||||
{
|
||||
@Override
|
||||
public void succeeded(C result)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
Log.getLogger(this.getClass()).warn(x);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -16,21 +16,29 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.websocket.server.callbacks;
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
|
||||
public class WebSocketOpenCallback extends FutureCallback<String>
|
||||
public class PromisingCallback<R> implements Callback
|
||||
{
|
||||
@Override
|
||||
public void completed(String context)
|
||||
private final Promise<R> _promise;
|
||||
private final R _result;
|
||||
|
||||
public PromisingCallback(Promise<R> promise, R result)
|
||||
{
|
||||
// TODO notify API on connection open
|
||||
_promise=promise;
|
||||
_result=result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
_promise.succeeded(_result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void failed(String context, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
// TODO notify API on open failure
|
||||
_promise.failed(x);
|
||||
}
|
||||
|
||||
}
|
|
@ -25,5 +25,5 @@ import java.util.concurrent.Future;
|
|||
*/
|
||||
public interface Graceful
|
||||
{
|
||||
public <C> Future<C> shutdown(C c);
|
||||
public Future<Void> shutdown();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class BlockingCallbackTest
|
|||
public void testDone() throws Exception
|
||||
{
|
||||
BlockingCallback fcb= _factory.newBlockingCallback();
|
||||
fcb.completed(fcb.getPhase());
|
||||
fcb.succeeded();
|
||||
long start=System.currentTimeMillis();
|
||||
fcb.block();
|
||||
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
|
||||
|
@ -101,7 +101,7 @@ public class BlockingCallbackTest
|
|||
{
|
||||
latch.countDown();
|
||||
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
|
||||
fcb.completed(fcb.getPhase());
|
||||
fcb.succeeded();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class BlockingCallbackTest
|
|||
{
|
||||
BlockingCallback fcb= _factory.newBlockingCallback();
|
||||
Exception ex=new Exception("FAILED");
|
||||
fcb.failed(fcb.getPhase(),ex);
|
||||
fcb.failed(ex);
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
try
|
||||
|
@ -146,7 +146,7 @@ public class BlockingCallbackTest
|
|||
{
|
||||
latch.countDown();
|
||||
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
|
||||
fcb.failed(fcb.getPhase(),ex);
|
||||
fcb.failed(ex);
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -30,19 +27,13 @@ import java.util.concurrent.TimeoutException;
|
|||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
public class FutureCallbackTest
|
||||
{
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testNotDone()
|
||||
{
|
||||
FutureCallback<String> fcb= new FutureCallback<>();
|
||||
FutureCallback fcb= new FutureCallback();
|
||||
Assert.assertFalse(fcb.isDone());
|
||||
Assert.assertFalse(fcb.isCancelled());
|
||||
}
|
||||
|
@ -50,7 +41,7 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testGetNotDone() throws Exception
|
||||
{
|
||||
FutureCallback<String> fcb= new FutureCallback<>();
|
||||
FutureCallback fcb= new FutureCallback();
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
try
|
||||
|
@ -67,20 +58,20 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testDone() throws Exception
|
||||
{
|
||||
FutureCallback<String> fcb= new FutureCallback<>();
|
||||
fcb.completed("Ctx");
|
||||
FutureCallback fcb= new FutureCallback();
|
||||
fcb.succeeded();
|
||||
Assert.assertTrue(fcb.isDone());
|
||||
Assert.assertFalse(fcb.isCancelled());
|
||||
|
||||
long start=System.currentTimeMillis();
|
||||
Assert.assertEquals("Ctx",fcb.get());
|
||||
Assert.assertEquals(null,fcb.get());
|
||||
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(500L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDone() throws Exception
|
||||
{
|
||||
final FutureCallback<String> fcb= new FutureCallback<>();
|
||||
final FutureCallback fcb= new FutureCallback();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
new Thread(new Runnable(){
|
||||
|
@ -88,13 +79,13 @@ public class FutureCallbackTest
|
|||
{
|
||||
latch.countDown();
|
||||
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
|
||||
fcb.completed("Ctx");
|
||||
fcb.succeeded();
|
||||
}
|
||||
}).start();
|
||||
|
||||
latch.await();
|
||||
long start=System.currentTimeMillis();
|
||||
Assert.assertEquals("Ctx",fcb.get(10000,TimeUnit.MILLISECONDS));
|
||||
Assert.assertEquals(null,fcb.get(10000,TimeUnit.MILLISECONDS));
|
||||
Assert.assertThat(System.currentTimeMillis()-start,Matchers.greaterThan(10L));
|
||||
Assert.assertThat(System.currentTimeMillis()-start,Matchers.lessThan(1000L));
|
||||
|
||||
|
@ -107,9 +98,9 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testFailed() throws Exception
|
||||
{
|
||||
FutureCallback<String> fcb= new FutureCallback<>();
|
||||
FutureCallback fcb= new FutureCallback();
|
||||
Exception ex=new Exception("FAILED");
|
||||
fcb.failed("Ctx",ex);
|
||||
fcb.failed(ex);
|
||||
Assert.assertTrue(fcb.isDone());
|
||||
Assert.assertFalse(fcb.isCancelled());
|
||||
|
||||
|
@ -129,7 +120,7 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testGetFailed() throws Exception
|
||||
{
|
||||
final FutureCallback<String> fcb= new FutureCallback<>();
|
||||
final FutureCallback fcb= new FutureCallback();
|
||||
final Exception ex=new Exception("FAILED");
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
|
@ -138,7 +129,7 @@ public class FutureCallbackTest
|
|||
{
|
||||
latch.countDown();
|
||||
try{TimeUnit.MILLISECONDS.sleep(100);}catch(Exception e){e.printStackTrace();}
|
||||
fcb.failed("Ctx",ex);
|
||||
fcb.failed(ex);
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
@ -165,7 +156,7 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testCancelled() throws Exception
|
||||
{
|
||||
FutureCallback<String> fcb= new FutureCallback<>();
|
||||
FutureCallback fcb= new FutureCallback();
|
||||
fcb.cancel(true);
|
||||
Assert.assertTrue(fcb.isDone());
|
||||
Assert.assertTrue(fcb.isCancelled());
|
||||
|
@ -186,7 +177,7 @@ public class FutureCallbackTest
|
|||
@Test
|
||||
public void testGetCancelled() throws Exception
|
||||
{
|
||||
final FutureCallback<String> fcb= new FutureCallback<>();
|
||||
final FutureCallback fcb= new FutureCallback();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
new Thread(new Runnable(){
|
||||
|
|
|
@ -20,8 +20,8 @@ package org.eclipse.jetty.websocket.client;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
|
@ -30,7 +30,7 @@ import org.eclipse.jetty.websocket.common.events.EventDriver;
|
|||
|
||||
public interface WebSocketClient
|
||||
{
|
||||
public FutureCallback<UpgradeResponse> connect(URI websocketUri) throws IOException;
|
||||
public Future<UpgradeResponse> connect(URI websocketUri) throws IOException;
|
||||
|
||||
public WebSocketClientFactory getFactory();
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Locale;
|
|||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
|
@ -114,7 +115,7 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
}
|
||||
}
|
||||
|
||||
public FutureCallback<UpgradeResponse> connectPhysical(DefaultWebSocketClient client) throws IOException
|
||||
public Future<UpgradeResponse> connectPhysical(DefaultWebSocketClient client) throws IOException
|
||||
{
|
||||
SocketChannel channel = SocketChannel.open();
|
||||
SocketAddress bindAddress = client.getFactory().getBindAddress();
|
||||
|
@ -137,7 +138,7 @@ public class ConnectionManager extends ContainerLifeCycle
|
|||
return client;
|
||||
}
|
||||
|
||||
public FutureCallback<UpgradeResponse> connectVirtual(WebSocketClient client)
|
||||
public Future<UpgradeResponse> connectVirtual(WebSocketClient client)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
|
|
@ -21,8 +21,10 @@ package org.eclipse.jetty.websocket.client.internal;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -41,7 +43,7 @@ import org.eclipse.jetty.websocket.common.events.EventDriver;
|
|||
/**
|
||||
* WebSocketClient for working with Upgrade (request and response), and establishing connections to the websocket URI of your choice.
|
||||
*/
|
||||
public class DefaultWebSocketClient extends FutureCallback<UpgradeResponse> implements WebSocketClient
|
||||
public class DefaultWebSocketClient extends FuturePromise<UpgradeResponse> implements WebSocketClient
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(DefaultWebSocketClient.class);
|
||||
|
||||
|
@ -72,10 +74,10 @@ public class DefaultWebSocketClient extends FutureCallback<UpgradeResponse> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(UpgradeResponse context)
|
||||
public void succeeded(UpgradeResponse response)
|
||||
{
|
||||
LOG.debug("completed() - {}",context);
|
||||
super.completed(context);
|
||||
LOG.debug("completed() - {}",response);
|
||||
super.succeeded(response);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -84,7 +86,7 @@ public class DefaultWebSocketClient extends FutureCallback<UpgradeResponse> impl
|
|||
* @see org.eclipse.jetty.websocket.client.internal.WebSocketClient#connect(java.net.URI)
|
||||
*/
|
||||
@Override
|
||||
public FutureCallback<UpgradeResponse> connect(URI websocketUri) throws IOException
|
||||
public Future<UpgradeResponse> connect(URI websocketUri) throws IOException
|
||||
{
|
||||
if (!factory.isStarted())
|
||||
{
|
||||
|
@ -111,7 +113,7 @@ public class DefaultWebSocketClient extends FutureCallback<UpgradeResponse> impl
|
|||
this.websocketUri = websocketUri;
|
||||
|
||||
// Validate websocket URI
|
||||
FutureCallback<UpgradeResponse> result = null;
|
||||
Future<UpgradeResponse> result = null;
|
||||
|
||||
LOG.debug("connect({})",websocketUri);
|
||||
|
||||
|
@ -128,11 +130,11 @@ public class DefaultWebSocketClient extends FutureCallback<UpgradeResponse> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(UpgradeResponse context, Throwable cause)
|
||||
public void failed(Throwable cause)
|
||||
{
|
||||
LOG.debug("failed() - {}, {}",context,cause);
|
||||
LOG.debug("failed() - {}",cause);
|
||||
LOG.info(cause);
|
||||
super.failed(context,cause);
|
||||
super.failed(cause);
|
||||
}
|
||||
|
||||
protected ClientUpgradeRequest getClientUpgradeRequest()
|
||||
|
|
|
@ -30,11 +30,13 @@ import org.eclipse.jetty.io.ByteBufferPool;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.FutureCallback;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeException;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
||||
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Extension;
|
||||
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
|
||||
|
@ -53,13 +55,13 @@ import org.eclipse.jetty.websocket.common.events.EventDriver;
|
|||
*/
|
||||
public class UpgradeConnection extends AbstractConnection
|
||||
{
|
||||
public class SendUpgradeRequest extends FutureCallback<String> implements Runnable
|
||||
public class SendUpgradeRequest extends FutureCallback implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void completed(String context)
|
||||
public void succeeded()
|
||||
{
|
||||
// Writing the request header is complete.
|
||||
super.completed(context);
|
||||
super.succeeded();
|
||||
// start the interest in fill
|
||||
fillInterested();
|
||||
}
|
||||
|
@ -72,7 +74,7 @@ public class UpgradeConnection extends AbstractConnection
|
|||
String rawRequest = request.generate();
|
||||
|
||||
ByteBuffer buf = BufferUtil.toBuffer(rawRequest,StringUtil.__UTF8_CHARSET);
|
||||
getEndPoint().write("REQ",this,buf);
|
||||
getEndPoint().write(this,buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,7 @@ public class UpgradeConnection extends AbstractConnection
|
|||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
client.failed(null,new RuntimeException("Invalid Upgrade Request structure",e));
|
||||
client.failed(new RuntimeException("Invalid Upgrade Request structure",e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,9 +115,9 @@ public class UpgradeConnection extends AbstractConnection
|
|||
}
|
||||
}
|
||||
|
||||
private void notifyConnect()
|
||||
private void notifyConnect(UpgradeResponse response)
|
||||
{
|
||||
client.completed(client.getUpgradeResponse());
|
||||
client.succeeded(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -183,7 +185,7 @@ public class UpgradeConnection extends AbstractConnection
|
|||
// Got a response!
|
||||
client.setUpgradeResponse(resp);
|
||||
validateResponse(resp);
|
||||
notifyConnect();
|
||||
notifyConnect(resp);
|
||||
upgradeConnection(resp);
|
||||
return false; // do no more reading
|
||||
}
|
||||
|
@ -193,14 +195,14 @@ public class UpgradeConnection extends AbstractConnection
|
|||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
client.failed(null,e);
|
||||
client.failed(e);
|
||||
disconnect(false);
|
||||
return false;
|
||||
}
|
||||
catch (UpgradeException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
client.failed(null,e);
|
||||
client.failed(e);
|
||||
disconnect(false);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public class WebSocketClientSelectorManager extends SelectorManager
|
|||
catch (IOException e)
|
||||
{
|
||||
LOG.debug(e);
|
||||
client.failed(null,e);
|
||||
client.failed(e);
|
||||
// rethrow
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public class ClientConnectTest
|
|||
WebSocketClient client = factory.newWebSocketClient(wsocket);
|
||||
|
||||
URI wsUri = server.getWsUri();
|
||||
FutureCallback<UpgradeResponse> future = client.connect(wsUri);
|
||||
Future<UpgradeResponse> future = client.connect(wsUri);
|
||||
|
||||
ServerConnection connection = server.accept();
|
||||
connection.readRequest();
|
||||
|
@ -109,7 +109,7 @@ public class ClientConnectTest
|
|||
WebSocketClient client = factory.newWebSocketClient(wsocket);
|
||||
|
||||
URI wsUri = server.getWsUri();
|
||||
FutureCallback<UpgradeResponse> future = client.connect(wsUri);
|
||||
Future<UpgradeResponse> future = client.connect(wsUri);
|
||||
|
||||
ServerConnection connection = server.accept();
|
||||
connection.readRequest();
|
||||
|
|
|
@ -104,7 +104,7 @@ public class SlowClientTest
|
|||
writer.setMessageCount(messageCount);
|
||||
writer.setMessage("Hello");
|
||||
// writer.setExchanger(exchanger);
|
||||
writer.setSlowness(50);
|
||||
writer.setSlowness(10);
|
||||
writer.start();
|
||||
writer.join();
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ public class SlowServerTest
|
|||
writer.setMessageCount(messageCount);
|
||||
writer.setMessage("Hello");
|
||||
// writer.setExchanger(exchanger);
|
||||
writer.setSlowness(50);
|
||||
writer.setSlowness(10);
|
||||
writer.start();
|
||||
writer.join();
|
||||
|
||||
|
|
|
@ -544,11 +544,11 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
|
|||
|
||||
try
|
||||
{
|
||||
endpoint.write(null,frameBytes,buffer);
|
||||
endpoint.write(frameBytes,buffer);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
frameBytes.failed(null,t);
|
||||
frameBytes.failed(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ public class ControlFrameBytes extends FrameBytes
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Void context)
|
||||
public void succeeded()
|
||||
{
|
||||
LOG.debug("completed() - frame: {}",frame);
|
||||
connection.getBufferPool().release(buffer);
|
||||
|
||||
super.completed(context);
|
||||
super.succeeded();
|
||||
|
||||
if (frame.getType().getOpCode() == OpCode.CLOSE)
|
||||
{
|
||||
|
|
|
@ -35,11 +35,11 @@ public class DataFrameBytes extends FrameBytes
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Void result)
|
||||
public void succeeded()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("completed({}) - frame.remaining() = {}",result,frame.remaining());
|
||||
LOG.debug("completed() - frame.remaining() = {}",frame.remaining());
|
||||
}
|
||||
|
||||
connection.getBufferPool().release(buffer);
|
||||
|
@ -56,7 +56,7 @@ public class DataFrameBytes extends FrameBytes
|
|||
else
|
||||
{
|
||||
LOG.debug("Send complete");
|
||||
super.completed(result);
|
||||
super.succeeded();
|
||||
}
|
||||
connection.flush();
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class DataFrameBytes extends FrameBytes
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
failed(null,x);
|
||||
failed(x);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.websocket.api.extensions.Frame;
|
||||
|
||||
public abstract class FrameBytes extends FutureCallback<Void> implements Runnable
|
||||
public abstract class FrameBytes extends FutureCallback implements Runnable
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger(FrameBytes.class);
|
||||
protected final AbstractWebSocketConnection connection;
|
||||
|
@ -52,12 +52,12 @@ public abstract class FrameBytes extends FutureCallback<Void> implements Runnabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void completed(Void v)
|
||||
public void succeeded()
|
||||
{
|
||||
super.completed(v);
|
||||
super.succeeded();
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("completed({}) - {}",v,this.getClass().getName());
|
||||
LOG.debug("completed() - {}",this.getClass().getName());
|
||||
}
|
||||
cancelTask();
|
||||
connection.complete(this);
|
||||
|
@ -65,17 +65,17 @@ public abstract class FrameBytes extends FutureCallback<Void> implements Runnabl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void failed(Void v, Throwable x)
|
||||
public void failed(Throwable x)
|
||||
{
|
||||
super.failed(v,x);
|
||||
super.failed(x);
|
||||
if (x instanceof EofException)
|
||||
{
|
||||
// Abbreviate the EofException
|
||||
LOG.warn("failed(" + v + ") - " + EofException.class);
|
||||
LOG.warn("failed() - " + EofException.class);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.warn("failed(" + v + ")",x);
|
||||
LOG.warn("failed()",x);
|
||||
}
|
||||
cancelTask();
|
||||
frame.notifySendFailed(x);
|
||||
|
@ -88,7 +88,7 @@ public abstract class FrameBytes extends FutureCallback<Void> implements Runnabl
|
|||
{
|
||||
// If this occurs we had a timeout!
|
||||
connection.close();
|
||||
failed(null,new InterruptedByTimeoutException());
|
||||
failed(new InterruptedByTimeoutException());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,7 +56,7 @@ public class HttpTransportOverMux implements HttpTransport
|
|||
@Override
|
||||
public void send(ResponseInfo info, ByteBuffer responseBodyContent, boolean lastContent) throws IOException
|
||||
{
|
||||
send(info,responseBodyContent,lastContent,streamBlocker.getPhase(),streamBlocker);
|
||||
send(info,responseBodyContent,lastContent,streamBlocker);
|
||||
try
|
||||
{
|
||||
streamBlocker.block();
|
||||
|
@ -72,7 +72,7 @@ public class HttpTransportOverMux implements HttpTransport
|
|||
}
|
||||
|
||||
@Override
|
||||
public <C> void send(ResponseInfo info, ByteBuffer responseBodyContent, boolean lastContent, C context, Callback<C> callback)
|
||||
public void send(ResponseInfo info, ByteBuffer responseBodyContent, boolean lastContent, Callback callback)
|
||||
{
|
||||
if (lastContent == false)
|
||||
{
|
||||
|
|
|
@ -36,10 +36,9 @@ import org.junit.Assert;
|
|||
|
||||
public class OutgoingFramesCapture implements OutgoingFrames
|
||||
{
|
||||
public static class Write<C>
|
||||
public static class Write
|
||||
{
|
||||
public C context;
|
||||
public Callback<C> callback;
|
||||
public Callback callback;
|
||||
public Frame frame;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue