Search in sources :

Example 36 with DatagramChannel

use of java.nio.channels.DatagramChannel in project tomcat70 by apache.

the class NioReplicationTask method sendAck.

/**
 * send a reply-acknowledgement (6,2,3), sends it doing a busy write, the ACK is so small
 * that it should always go to the buffer
 * @param key
 * @param channel
 */
protected void sendAck(SelectionKey key, WritableByteChannel channel, byte[] command, SocketAddress udpaddr) {
    try {
        ByteBuffer buf = ByteBuffer.wrap(command);
        int total = 0;
        if (channel instanceof DatagramChannel) {
            DatagramChannel dchannel = (DatagramChannel) channel;
            // TODO check optimization, one channel per thread?
            while (total < command.length) {
                total += dchannel.send(buf, udpaddr);
            }
        } else {
            while (total < command.length) {
                total += channel.write(buf);
            }
        }
        if (log.isTraceEnabled()) {
            log.trace("ACK sent to " + ((channel instanceof SocketChannel) ? ((SocketChannel) channel).socket().getInetAddress() : ((DatagramChannel) channel).socket().getInetAddress()));
        }
    } catch (java.io.IOException x) {
        log.warn("Unable to send ACK back through channel, channel disconnected?: " + x.getMessage());
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) DatagramChannel(java.nio.channels.DatagramChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Example 37 with DatagramChannel

use of java.nio.channels.DatagramChannel in project tomcat70 by apache.

the class NioReplicationTask method drainChannel.

/**
 * The actual code which drains the channel associated with
 * the given key.  This method assumes the key has been
 * modified prior to invocation to turn off selection
 * interest in OP_READ.  When this method completes it
 * re-enables OP_READ and calls wakeup() on the selector
 * so the selector will resume watching this channel.
 */
protected void drainChannel(final SelectionKey key, ObjectReader reader) throws Exception {
    reader.setLastAccess(System.currentTimeMillis());
    reader.access();
    ReadableByteChannel channel = (ReadableByteChannel) key.channel();
    int count = -1;
    // make buffer empty
    buffer.clear();
    SocketAddress saddr = null;
    if (channel instanceof SocketChannel) {
        // loop while data available, channel is non-blocking
        while ((count = channel.read(buffer)) > 0) {
            // make buffer readable
            buffer.flip();
            if (buffer.hasArray())
                reader.append(buffer.array(), 0, count, false);
            else
                reader.append(buffer, count, false);
            // make buffer empty
            buffer.clear();
            // do we have at least one package?
            if (reader.hasPackage())
                break;
        }
    } else if (channel instanceof DatagramChannel) {
        DatagramChannel dchannel = (DatagramChannel) channel;
        saddr = dchannel.receive(buffer);
        // make buffer readable
        buffer.flip();
        if (buffer.hasArray())
            reader.append(buffer.array(), 0, buffer.limit() - buffer.position(), false);
        else
            reader.append(buffer, buffer.limit() - buffer.position(), false);
        // make buffer empty
        buffer.clear();
        // did we get a package
        count = reader.hasPackage() ? 1 : -1;
    }
    int pkgcnt = reader.count();
    if (count < 0 && pkgcnt == 0) {
        // end of stream, and no more packages to process
        remoteEof(key);
        return;
    }
    ChannelMessage[] msgs = pkgcnt == 0 ? ChannelData.EMPTY_DATA_ARRAY : reader.execute();
    // register to read new data, before we send it off to avoid dead locks
    registerForRead(key, reader);
    for (int i = 0; i < msgs.length; i++) {
        /**
         * Use send ack here if you want to ack the request to the remote
         * server before completing the request
         * This is considered an asynchronous request
         */
        if (ChannelData.sendAckAsync(msgs[i].getOptions()))
            sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
        try {
            if (Logs.MESSAGES.isTraceEnabled()) {
                try {
                    Logs.MESSAGES.trace("NioReplicationThread - Received msg:" + new UniqueId(msgs[i].getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()));
                } catch (Throwable t) {
                }
            }
            // process the message
            getCallback().messageDataReceived(msgs[i]);
            /**
             * Use send ack here if you want the request to complete on this
             * server before sending the ack to the remote server
             * This is considered a synchronized request
             */
            if (ChannelData.sendAckSync(msgs[i].getOptions()))
                sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
        } catch (RemoteProcessException e) {
            if (log.isDebugEnabled())
                log.error("Processing of cluster message failed.", e);
            if (ChannelData.sendAckSync(msgs[i].getOptions()))
                sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
        } catch (Exception e) {
            log.error("Processing of cluster message failed.", e);
            if (ChannelData.sendAckSync(msgs[i].getOptions()))
                sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
        }
        if (getUseBufferPool()) {
            BufferPool.getBufferPool().returnBuffer(msgs[i].getMessage());
            msgs[i].setMessage(null);
        }
    }
    if (count < 0) {
        remoteEof(key);
        return;
    }
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) SocketChannel(java.nio.channels.SocketChannel) UniqueId(org.apache.catalina.tribes.UniqueId) DatagramChannel(java.nio.channels.DatagramChannel) WritableByteChannel(java.nio.channels.WritableByteChannel) RemoteProcessException(org.apache.catalina.tribes.RemoteProcessException) CancelledKeyException(java.nio.channels.CancelledKeyException) IOException(java.io.IOException) ChannelMessage(org.apache.catalina.tribes.ChannelMessage) RemoteProcessException(org.apache.catalina.tribes.RemoteProcessException) SocketAddress(java.net.SocketAddress)

Example 38 with DatagramChannel

use of java.nio.channels.DatagramChannel in project tomcat70 by apache.

the class NioReplicationTask method run.

// loop forever waiting for work to do
@Override
public synchronized void run() {
    if (buffer == null) {
        int size = getRxBufSize();
        if (key.channel() instanceof DatagramChannel) {
            size = ChannelReceiver.MAX_UDP_SIZE;
        }
        if ((getOptions() & OPTION_DIRECT_BUFFER) == OPTION_DIRECT_BUFFER) {
            buffer = ByteBuffer.allocateDirect(size);
        } else {
            buffer = ByteBuffer.allocate(size);
        }
    } else {
        buffer.clear();
    }
    if (key == null) {
        // just in case
        return;
    }
    if (log.isTraceEnabled())
        log.trace("Servicing key:" + key);
    try {
        ObjectReader reader = (ObjectReader) key.attachment();
        if (reader == null) {
            if (log.isTraceEnabled())
                log.trace("No object reader, cancelling:" + key);
            cancelKey(key);
        } else {
            if (log.isTraceEnabled())
                log.trace("Draining channel:" + key);
            drainChannel(key, reader);
        }
    } catch (Exception e) {
        // end expire after a certain time.
        if (e instanceof CancelledKeyException) {
        // do nothing
        } else if (e instanceof IOException) {
            // dont spew out stack traces for IO exceptions unless debug is enabled.
            if (log.isDebugEnabled())
                log.debug("IOException in replication worker, unable to drain channel. Probable cause: Keep alive socket closed[" + e.getMessage() + "].", e);
            else
                log.warn("IOException in replication worker, unable to drain channel. Probable cause: Keep alive socket closed[" + e.getMessage() + "].");
        } else if (log.isErrorEnabled()) {
            // this is a real error, log it.
            log.error("Exception caught in TcpReplicationThread.drainChannel.", e);
        }
        cancelKey(key);
    } finally {
    }
    key = null;
    // done, ready for more, return to pool
    getTaskPool().returnWorker(this);
}
Also used : CancelledKeyException(java.nio.channels.CancelledKeyException) DatagramChannel(java.nio.channels.DatagramChannel) ObjectReader(org.apache.catalina.tribes.io.ObjectReader) IOException(java.io.IOException) RemoteProcessException(org.apache.catalina.tribes.RemoteProcessException) CancelledKeyException(java.nio.channels.CancelledKeyException) IOException(java.io.IOException)

Example 39 with DatagramChannel

use of java.nio.channels.DatagramChannel in project AndroidAsync by koush.

the class AsyncServer method openDatagram.

public AsyncDatagramSocket openDatagram(final InetAddress host, final int port, final boolean reuseAddress) {
    final AsyncDatagramSocket handler = new AsyncDatagramSocket();
    // ugh.. this should really be post to make it nonblocking...
    // but i want datagrams to be immediately writable.
    // they're not really used anyways.
    Runnable runnable = () -> {
        final DatagramChannel socket;
        try {
            socket = DatagramChannel.open();
        } catch (Exception e) {
            return;
        }
        try {
            handler.attach(socket);
            InetSocketAddress address;
            if (host == null)
                address = new InetSocketAddress(port);
            else
                address = new InetSocketAddress(host, port);
            if (reuseAddress)
                socket.socket().setReuseAddress(reuseAddress);
            socket.socket().bind(address);
            handleSocket(handler);
        } catch (IOException e) {
            Log.e(LOGTAG, "Datagram error", e);
            StreamUtility.closeQuietly(socket);
        }
    };
    if (getAffinity() != Thread.currentThread()) {
        run(runnable);
        return handler;
    }
    runnable.run();
    return handler;
}
Also used : InetSocketAddress(java.net.InetSocketAddress) DatagramChannel(java.nio.channels.DatagramChannel) IOException(java.io.IOException) CancelledKeyException(java.nio.channels.CancelledKeyException) ClosedChannelException(java.nio.channels.ClosedChannelException) IOException(java.io.IOException) ClosedSelectorException(java.nio.channels.ClosedSelectorException)

Example 40 with DatagramChannel

use of java.nio.channels.DatagramChannel in project AndroidAsync by koush.

the class AsyncServer method createDatagram.

private Cancellable createDatagram(ValueFunction<InetAddress> inetAddressValueFunction, final int port, final boolean reuseAddress, FutureCallback<AsyncDatagramSocket> callback) {
    SimpleFuture<AsyncDatagramSocket> ret = new SimpleFuture<>();
    ret.setCallback(callback);
    post(() -> {
        DatagramChannel socket = null;
        try {
            socket = DatagramChannel.open();
            final AsyncDatagramSocket handler = new AsyncDatagramSocket();
            handler.attach(socket);
            InetSocketAddress address;
            if (inetAddressValueFunction == null)
                address = new InetSocketAddress(port);
            else
                address = new InetSocketAddress(inetAddressValueFunction.getValue(), port);
            if (reuseAddress)
                socket.socket().setReuseAddress(reuseAddress);
            socket.socket().bind(address);
            handleSocket(handler);
            if (!ret.setComplete(handler))
                socket.close();
        } catch (Exception e) {
            StreamUtility.closeQuietly(socket);
            ret.setComplete(e);
        }
    });
    return ret;
}
Also used : InetSocketAddress(java.net.InetSocketAddress) DatagramChannel(java.nio.channels.DatagramChannel) CancelledKeyException(java.nio.channels.CancelledKeyException) ClosedChannelException(java.nio.channels.ClosedChannelException) IOException(java.io.IOException) ClosedSelectorException(java.nio.channels.ClosedSelectorException) SimpleFuture(com.koushikdutta.async.future.SimpleFuture)

Aggregations

DatagramChannel (java.nio.channels.DatagramChannel)214 InetSocketAddress (java.net.InetSocketAddress)92 ByteBuffer (java.nio.ByteBuffer)71 IOException (java.io.IOException)58 MembershipKey (java.nio.channels.MembershipKey)22 DatagramSocket (java.net.DatagramSocket)21 SocketAddress (java.net.SocketAddress)21 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)20 SocketChannel (java.nio.channels.SocketChannel)17 SelectionKey (java.nio.channels.SelectionKey)16 InetAddress (java.net.InetAddress)13 Selector (java.nio.channels.Selector)13 Test (org.junit.Test)11 SocketException (java.net.SocketException)9 ClosedChannelException (java.nio.channels.ClosedChannelException)9 Histogram (org.HdrHistogram.Histogram)8 CancelledKeyException (java.nio.channels.CancelledKeyException)7 DatagramPacket (java.net.DatagramPacket)5 NetworkInterface (java.net.NetworkInterface)5 ArrayList (java.util.ArrayList)5