use of com.koushikdutta.async.future.Continuation in project AndroidAsync by koush.
the class AsyncSocketMiddleware method getSocket.
@Override
public Cancellable getSocket(final GetSocketData data) {
final Uri uri = data.request.getUri();
final int port = getSchemePort(data.request.getUri());
if (port == -1) {
return null;
}
data.state.put("socket-owner", this);
final String lookup = computeLookup(uri, port, data.request.getProxyHost(), data.request.getProxyPort());
ConnectionInfo info = getOrCreateConnectionInfo(lookup);
synchronized (AsyncSocketMiddleware.this) {
if (info.openCount >= maxConnectionCount) {
// wait for a connection queue to free up
SimpleCancellable queueCancel = new SimpleCancellable();
info.queue.add(data);
return queueCancel;
}
info.openCount++;
while (!info.sockets.isEmpty()) {
IdleSocketHolder idleSocketHolder = info.sockets.pop();
final AsyncSocket socket = idleSocketHolder.socket;
if (idleSocketHolder.idleTime + idleTimeoutMs < System.currentTimeMillis()) {
socket.setClosedCallback(null);
socket.close();
continue;
}
if (!socket.isOpen())
continue;
data.request.logd("Reusing keep-alive socket");
data.connectCallback.onConnectCompleted(null, socket);
// just a noop/dummy, as this can't actually be cancelled.
SimpleCancellable ret = new SimpleCancellable();
ret.setComplete();
return ret;
}
}
if (!connectAllAddresses || proxyHost != null || data.request.getProxyHost() != null) {
// just default to connecting to a single address
data.request.logd("Connecting socket");
String unresolvedHost;
int unresolvedPort;
boolean proxied = false;
if (data.request.getProxyHost() == null && proxyHost != null)
data.request.enableProxy(proxyHost, proxyPort);
if (data.request.getProxyHost() != null) {
unresolvedHost = data.request.getProxyHost();
unresolvedPort = data.request.getProxyPort();
proxied = true;
} else {
unresolvedHost = uri.getHost();
unresolvedPort = port;
}
if (proxied) {
data.request.logv("Using proxy: " + unresolvedHost + ":" + unresolvedPort);
}
return mClient.getServer().connectSocket(unresolvedHost, unresolvedPort, wrapCallback(data, uri, port, proxied, data.connectCallback));
}
// try to connect to everything...
data.request.logv("Resolving domain and connecting to all available addresses");
return mClient.getServer().getAllByName(uri.getHost()).then(new TransformFuture<AsyncSocket, InetAddress[]>() {
Exception lastException;
@Override
protected void error(Exception e) {
super.error(e);
wrapCallback(data, uri, port, false, data.connectCallback).onConnectCompleted(e, null);
}
@Override
protected void transform(final InetAddress[] result) throws Exception {
Continuation keepTrying = new Continuation(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
// if it completed, that means that the connection failed
if (lastException == null)
lastException = new ConnectionFailedException("Unable to connect to remote address");
if (setComplete(lastException)) {
wrapCallback(data, uri, port, false, data.connectCallback).onConnectCompleted(lastException, null);
}
}
});
for (final InetAddress address : result) {
final String inetSockAddress = String.format(Locale.ENGLISH, "%s:%s", address, port);
keepTrying.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, final CompletedCallback next) throws Exception {
data.request.logv("attempting connection to " + inetSockAddress);
mClient.getServer().connectSocket(new InetSocketAddress(address, port), wrapCallback(data, uri, port, false, new ConnectCallback() {
@Override
public void onConnectCompleted(Exception ex, AsyncSocket socket) {
if (isDone()) {
lastException = new Exception("internal error during connect to " + inetSockAddress);
next.onCompleted(null);
return;
}
// try the next address
if (ex != null) {
lastException = ex;
next.onCompleted(null);
return;
}
// if the socket is no longer needed, just hang onto it...
if (isDone() || isCancelled()) {
data.request.logd("Recycling extra socket leftover from cancelled operation");
idleSocket(socket);
recycleSocket(socket, data.request);
return;
}
if (setComplete(null, socket)) {
data.connectCallback.onConnectCompleted(null, socket);
}
}
}));
}
});
}
keepTrying.start();
}
});
}
use of com.koushikdutta.async.future.Continuation in project AndroidAsync by koush.
the class FutureTests method testContinuationArray.
public void testContinuationArray() throws Exception {
final ArrayList<Integer> results = new ArrayList<Integer>();
final Semaphore semaphore = new Semaphore(0);
final Continuation c = new Continuation(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
semaphore.release();
}
});
for (int i = 0; i < 10; i++) {
final int j = i;
c.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, CompletedCallback next) throws Exception {
results.add(j);
next.onCompleted(null);
}
});
}
new Thread() {
public void run() {
c.start();
}
;
}.start();
assertTrue(semaphore.tryAcquire(3000, TimeUnit.MILLISECONDS));
assertEquals(10, results.size());
for (int i = 0; i < 10; i++) {
assertEquals((int) results.get(i), i);
}
}
use of com.koushikdutta.async.future.Continuation in project AndroidAsync by koush.
the class FutureTests method testFutureChain.
public void testFutureChain() throws Exception {
final Semaphore semaphore = new Semaphore(0);
final Continuation c = new Continuation(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
semaphore.release();
}
});
IntegerFuture i1;
c.add(i1 = IntegerFuture.create(2, 200));
IntegerFuture i2;
c.add(i2 = IntegerFuture.create(3, 200));
new Thread() {
public void run() {
c.start();
}
;
}.start();
assertTrue(semaphore.tryAcquire(3000, TimeUnit.MILLISECONDS));
assertEquals((int) i1.get(), 2);
assertEquals((int) i2.get(), 3);
}
use of com.koushikdutta.async.future.Continuation in project AndroidAsync by koush.
the class FutureTests method testContinuationFail.
public void testContinuationFail() throws Exception {
final Semaphore semaphore = new Semaphore(0);
final Continuation c = new Continuation(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
assertNotNull(ex);
semaphore.release();
}
});
c.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, CompletedCallback next) throws Exception {
throw new Exception("fail");
}
});
new Thread() {
public void run() {
c.start();
}
;
}.start();
assertTrue(semaphore.tryAcquire(3000, TimeUnit.MILLISECONDS));
}
use of com.koushikdutta.async.future.Continuation in project AndroidAsync by koush.
the class FutureTests method testContinuation.
public void testContinuation() throws Exception {
final Semaphore semaphore = new Semaphore(0);
someValue = 0;
final Continuation c = new Continuation(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
assertNull(ex);
semaphore.release();
}
});
c.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, final CompletedCallback next) throws Exception {
new Thread() {
public void run() {
someValue++;
next.onCompleted(null);
}
;
}.start();
}
});
c.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, final CompletedCallback next) throws Exception {
new Thread() {
public void run() {
someValue++;
next.onCompleted(null);
}
;
}.start();
}
});
c.add(new ContinuationCallback() {
@Override
public void onContinue(Continuation continuation, final CompletedCallback next) throws Exception {
someValue++;
next.onCompleted(null);
}
});
new Thread() {
public void run() {
c.start();
}
;
}.start();
assertTrue(semaphore.tryAcquire(3000, TimeUnit.MILLISECONDS));
assertEquals(someValue, 3);
}
Aggregations