Search in sources :

Example 1 with ContinuationCallback

use of com.koushikdutta.async.callback.ContinuationCallback 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();
        }
    });
}
Also used : Continuation(com.koushikdutta.async.future.Continuation) CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) InetSocketAddress(java.net.InetSocketAddress) Uri(android.net.Uri) AsyncSocket(com.koushikdutta.async.AsyncSocket) ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback) SimpleCancellable(com.koushikdutta.async.future.SimpleCancellable) ConnectCallback(com.koushikdutta.async.callback.ConnectCallback) InetAddress(java.net.InetAddress)

Example 2 with ContinuationCallback

use of com.koushikdutta.async.callback.ContinuationCallback 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);
    }
}
Also used : Continuation(com.koushikdutta.async.future.Continuation) CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) ArrayList(java.util.ArrayList) ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback) Semaphore(java.util.concurrent.Semaphore) CancellationException(java.util.concurrent.CancellationException) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException)

Example 3 with ContinuationCallback

use of com.koushikdutta.async.callback.ContinuationCallback 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));
}
Also used : Continuation(com.koushikdutta.async.future.Continuation) CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback) Semaphore(java.util.concurrent.Semaphore) CancellationException(java.util.concurrent.CancellationException) TimeoutException(java.util.concurrent.TimeoutException) ExecutionException(java.util.concurrent.ExecutionException)

Example 4 with ContinuationCallback

use of com.koushikdutta.async.callback.ContinuationCallback in project AndroidAsync by koush.

the class Continuation method add.

public Continuation add(final DependentFuture future) {
    future.setParent(this);
    add(new ContinuationCallback() {

        @Override
        public void onContinue(Continuation continuation, CompletedCallback next) throws Exception {
            future.get();
            next.onCompleted(null);
        }
    });
    return this;
}
Also used : CompletedCallback(com.koushikdutta.async.callback.CompletedCallback) ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback)

Example 5 with ContinuationCallback

use of com.koushikdutta.async.callback.ContinuationCallback in project AndroidAsync by koush.

the class Continuation method next.

private void next() {
    if (inNext)
        return;
    while (mCallbacks.size() > 0 && !waiting && !isDone() && !isCancelled()) {
        ContinuationCallback cb = mCallbacks.remove();
        try {
            inNext = true;
            waiting = true;
            cb.onContinue(this, wrap());
        } catch (Exception e) {
            reportCompleted(e);
        } finally {
            inNext = false;
        }
    }
    if (waiting)
        return;
    if (isDone())
        return;
    if (isCancelled())
        return;
    reportCompleted(null);
}
Also used : ContinuationCallback(com.koushikdutta.async.callback.ContinuationCallback)

Aggregations

ContinuationCallback (com.koushikdutta.async.callback.ContinuationCallback)9 CompletedCallback (com.koushikdutta.async.callback.CompletedCallback)8 Continuation (com.koushikdutta.async.future.Continuation)7 CancellationException (java.util.concurrent.CancellationException)5 ExecutionException (java.util.concurrent.ExecutionException)5 Semaphore (java.util.concurrent.Semaphore)5 TimeoutException (java.util.concurrent.TimeoutException)5 Uri (android.net.Uri)1 AsyncSocket (com.koushikdutta.async.AsyncSocket)1 ConnectCallback (com.koushikdutta.async.callback.ConnectCallback)1 SimpleCancellable (com.koushikdutta.async.future.SimpleCancellable)1 InetAddress (java.net.InetAddress)1 InetSocketAddress (java.net.InetSocketAddress)1 ArrayList (java.util.ArrayList)1