Search in sources :

Example 66 with SocketChannel

use of java.nio.channels.SocketChannel in project quorrabot by GloriousEggroll.

the class WebSocketServer method run.

// Runnable IMPLEMENTATION /////////////////////////////////////////////////
public void run() {
    synchronized (this) {
        if (selectorthread != null) {
            throw new IllegalStateException(getClass().getName() + " can only be started once.");
        }
        selectorthread = Thread.currentThread();
        if (isclosed.get()) {
            return;
        }
    }
    selectorthread.setName("WebsocketSelector" + selectorthread.getId());
    try {
        server = ServerSocketChannel.open();
        server.configureBlocking(false);
        ServerSocket socket = server.socket();
        socket.setReceiveBufferSize(WebSocketImpl.RCVBUF);
        socket.bind(address);
        selector = Selector.open();
        server.register(selector, server.validOps());
    } catch (IOException ex) {
        handleFatal(null, ex);
        return;
    }
    try {
        while (!selectorthread.isInterrupted()) {
            SelectionKey key = null;
            WebSocketImpl conn = null;
            try {
                selector.select();
                Set<SelectionKey> keys = selector.selectedKeys();
                Iterator<SelectionKey> i = keys.iterator();
                while (i.hasNext()) {
                    key = i.next();
                    if (!key.isValid()) {
                        // Object o = key.attachment();
                        continue;
                    }
                    if (key.isAcceptable()) {
                        if (!onConnect(key)) {
                            key.cancel();
                            continue;
                        }
                        SocketChannel channel = server.accept();
                        channel.configureBlocking(false);
                        WebSocketImpl w = wsf.createWebSocket(this, drafts, channel.socket());
                        w.key = channel.register(selector, SelectionKey.OP_READ, w);
                        w.channel = wsf.wrapChannel(channel, w.key);
                        i.remove();
                        allocateBuffers(w);
                        continue;
                    }
                    if (key.isReadable()) {
                        conn = (WebSocketImpl) key.attachment();
                        ByteBuffer buf = takeBuffer();
                        try {
                            if (SocketChannelIOHelper.read(buf, conn, conn.channel)) {
                                if (buf.hasRemaining()) {
                                    conn.inQueue.put(buf);
                                    queue(conn);
                                    i.remove();
                                    if (conn.channel instanceof WrappedByteChannel) {
                                        if (((WrappedByteChannel) conn.channel).isNeedRead()) {
                                            iqueue.add(conn);
                                        }
                                    }
                                } else {
                                    pushBuffer(buf);
                                }
                            } else {
                                pushBuffer(buf);
                            }
                        } catch (IOException e) {
                            pushBuffer(buf);
                            throw e;
                        }
                    }
                    if (key.isWritable()) {
                        conn = (WebSocketImpl) key.attachment();
                        if (SocketChannelIOHelper.batch(conn, conn.channel)) {
                            if (key.isValid()) {
                                key.interestOps(SelectionKey.OP_READ);
                            }
                        }
                    }
                }
                while (!iqueue.isEmpty()) {
                    conn = iqueue.remove(0);
                    WrappedByteChannel c = ((WrappedByteChannel) conn.channel);
                    ByteBuffer buf = takeBuffer();
                    try {
                        if (SocketChannelIOHelper.readMore(buf, conn, c)) {
                            iqueue.add(conn);
                        }
                        if (buf.hasRemaining()) {
                            conn.inQueue.put(buf);
                            queue(conn);
                        } else {
                            pushBuffer(buf);
                        }
                    } catch (IOException e) {
                        pushBuffer(buf);
                        throw e;
                    }
                }
            } catch (CancelledKeyException e) {
            // an other thread may cancel the key
            } catch (ClosedByInterruptException e) {
                // do the same stuff as when InterruptedException is thrown
                return;
            } catch (IOException ex) {
                if (key != null) {
                    key.cancel();
                }
                handleIOException(key, conn, ex);
            } catch (InterruptedException e) {
                // FIXME controlled shutdown (e.g. take care of buffermanagement)
                return;
            }
        }
    } catch (RuntimeException e) {
        // should hopefully never occur
        handleFatal(null, e);
    } finally {
        if (decoders != null) {
            for (WebSocketWorker w : decoders) {
                w.interrupt();
            }
        }
        if (server != null) {
            try {
                server.close();
            } catch (IOException e) {
                onError(null, e);
            }
        }
    }
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketChannel(java.nio.channels.SocketChannel) ServerSocketChannel(java.nio.channels.ServerSocketChannel) CancelledKeyException(java.nio.channels.CancelledKeyException) ServerSocket(java.net.ServerSocket) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) ClosedByInterruptException(java.nio.channels.ClosedByInterruptException) WrappedByteChannel(org.java_websocket.WrappedByteChannel) WebSocketImpl(org.java_websocket.WebSocketImpl)

Example 67 with SocketChannel

use of java.nio.channels.SocketChannel in project zm-mailbox by Zimbra.

the class ZimbraSocketAcceptor method accept.

@Override
protected NioSession accept(IoProcessor<NioSession> processor, ServerSocketChannel handle) throws Exception {
    SelectionKey key = handle.keyFor(selector);
    if ((key == null) || (!key.isValid()) || (!key.isAcceptable())) {
        return null;
    }
    // accept the connection from the client
    SocketChannel ch = handle.accept();
    if (ch == null) {
        return null;
    }
    return new NioSocketSession(this, processor, ch);
}
Also used : SelectionKey(java.nio.channels.SelectionKey) ServerSocketChannel(java.nio.channels.ServerSocketChannel) SocketChannel(java.nio.channels.SocketChannel)

Example 68 with SocketChannel

use of java.nio.channels.SocketChannel in project asterixdb by apache.

the class ReplicationManager method establishTxnLogReplicationHandshake.

/**
     * Opens a new connection with Active remote replicas and starts a listen thread per connection.
     */
private void establishTxnLogReplicationHandshake() {
    Map<String, SocketChannel> activeRemoteReplicasSockets = getActiveRemoteReplicasSockets();
    logsRepSockets = new SocketChannel[activeRemoteReplicasSockets.size()];
    int i = 0;
    //start a listener thread per connection
    for (Entry<String, SocketChannel> entry : activeRemoteReplicasSockets.entrySet()) {
        logsRepSockets[i] = entry.getValue();
        replicationListenerThreads.execute(new TxnLogsReplicationResponseListener(entry.getKey(), entry.getValue()));
        i++;
    }
    /**
         * establish log replication handshake
         */
    ByteBuffer handshakeBuffer = ByteBuffer.allocate(ReplicationProtocol.REPLICATION_REQUEST_TYPE_SIZE).putInt(ReplicationProtocol.ReplicationRequestType.REPLICATE_LOG.ordinal());
    handshakeBuffer.flip();
    //send handshake request
    for (SocketChannel replicaSocket : logsRepSockets) {
        try {
            NetworkingUtil.transferBufferToChannel(replicaSocket, handshakeBuffer);
        } catch (IOException e) {
            handleReplicationFailure(replicaSocket, e);
        } finally {
            handshakeBuffer.position(0);
        }
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Example 69 with SocketChannel

use of java.nio.channels.SocketChannel in project asterixdb by apache.

the class ReplicationManager method processJob.

/**
     * Processes the replication job based on its specifications
     *
     * @param job
     *            The replication job
     * @param replicasSockets
     *            The remote replicas sockets to send the request to.
     * @param requestBuffer
     *            The buffer to use to send the request.
     * @throws IOException
     */
private void processJob(IReplicationJob job, Map<String, SocketChannel> replicasSockets, ByteBuffer requestBuffer) throws IOException {
    try {
        //all of the job's files belong to a single storage partition.
        //get any of them to determine the partition from the file path.
        String jobFile = job.getJobFiles().iterator().next();
        IndexFileProperties indexFileRef = localResourceRepo.getIndexFileRef(jobFile);
        if (!replicationStrategy.isMatch(indexFileRef.getDatasetId())) {
            return;
        }
        int jobPartitionId = indexFileRef.getPartitionId();
        ByteBuffer responseBuffer = null;
        LSMIndexFileProperties asterixFileProperties = new LSMIndexFileProperties();
        if (requestBuffer == null) {
            requestBuffer = ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
        }
        boolean isLSMComponentFile = job.getJobType() == ReplicationJobType.LSM_COMPONENT;
        try {
            //if there isn't already a connection, establish a new one
            if (replicasSockets == null) {
                replicasSockets = getActiveRemoteReplicasSockets();
            }
            int remainingFiles = job.getJobFiles().size();
            if (job.getOperation() == ReplicationOperation.REPLICATE) {
                //if the replication job is an LSM_COMPONENT, its properties are sent first, then its files.
                ILSMIndexReplicationJob LSMComponentJob = null;
                if (job.getJobType() == ReplicationJobType.LSM_COMPONENT) {
                    //send LSMComponent properties
                    LSMComponentJob = (ILSMIndexReplicationJob) job;
                    LSMComponentProperties lsmCompProp = new LSMComponentProperties(LSMComponentJob, nodeId);
                    requestBuffer = ReplicationProtocol.writeLSMComponentPropertiesRequest(lsmCompProp, requestBuffer);
                    sendRequest(replicasSockets, requestBuffer);
                }
                for (String filePath : job.getJobFiles()) {
                    remainingFiles--;
                    Path path = Paths.get(filePath);
                    if (Files.notExists(path)) {
                        LOGGER.log(Level.SEVERE, "File deleted before replication: " + filePath);
                        continue;
                    }
                    LOGGER.log(Level.INFO, "Replicating file: " + filePath);
                    //open file for reading
                    try (RandomAccessFile fromFile = new RandomAccessFile(filePath, "r");
                        FileChannel fileChannel = fromFile.getChannel()) {
                        long fileSize = fileChannel.size();
                        if (LSMComponentJob != null) {
                            /**
                                 * since this is LSM_COMPONENT REPLICATE job, the job will contain
                                 * only the component being replicated.
                                 */
                            ILSMDiskComponent diskComponent = LSMComponentJob.getLSMIndexOperationContext().getComponentsToBeReplicated().get(0);
                            long lsnOffset = LSMIndexUtil.getComponentFileLSNOffset(LSMComponentJob.getLSMIndex(), diskComponent, filePath);
                            asterixFileProperties.initialize(filePath, fileSize, nodeId, isLSMComponentFile, lsnOffset, remainingFiles == 0);
                        } else {
                            asterixFileProperties.initialize(filePath, fileSize, nodeId, isLSMComponentFile, -1L, remainingFiles == 0);
                        }
                        requestBuffer = ReplicationProtocol.writeFileReplicationRequest(requestBuffer, asterixFileProperties, ReplicationRequestType.REPLICATE_FILE);
                        Iterator<Map.Entry<String, SocketChannel>> iterator = replicasSockets.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, SocketChannel> entry = iterator.next();
                            //if the remote replica is not interested in this partition, skip it.
                            if (!replica2PartitionsMap.get(entry.getKey()).contains(jobPartitionId)) {
                                continue;
                            }
                            SocketChannel socketChannel = entry.getValue();
                            //transfer request header & file
                            try {
                                NetworkingUtil.transferBufferToChannel(socketChannel, requestBuffer);
                                NetworkingUtil.sendFile(fileChannel, socketChannel);
                                if (asterixFileProperties.requiresAck()) {
                                    ReplicationRequestType responseType = waitForResponse(socketChannel, responseBuffer);
                                    if (responseType != ReplicationRequestType.ACK) {
                                        throw new IOException("Could not receive ACK from replica " + entry.getKey());
                                    }
                                }
                            } catch (IOException e) {
                                handleReplicationFailure(socketChannel, e);
                                iterator.remove();
                            } finally {
                                requestBuffer.position(0);
                            }
                        }
                    }
                }
            } else if (job.getOperation() == ReplicationOperation.DELETE) {
                for (String filePath : job.getJobFiles()) {
                    remainingFiles--;
                    asterixFileProperties.initialize(filePath, -1, nodeId, isLSMComponentFile, -1L, remainingFiles == 0);
                    ReplicationProtocol.writeFileReplicationRequest(requestBuffer, asterixFileProperties, ReplicationRequestType.DELETE_FILE);
                    Iterator<Map.Entry<String, SocketChannel>> iterator = replicasSockets.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, SocketChannel> entry = iterator.next();
                        //if the remote replica is not interested in this partition, skip it.
                        if (!replica2PartitionsMap.get(entry.getKey()).contains(jobPartitionId)) {
                            continue;
                        }
                        SocketChannel socketChannel = entry.getValue();
                        try {
                            sendRequest(replicasSockets, requestBuffer);
                            if (asterixFileProperties.requiresAck()) {
                                waitForResponse(socketChannel, responseBuffer);
                            }
                        } catch (IOException e) {
                            handleReplicationFailure(socketChannel, e);
                            iterator.remove();
                        } finally {
                            requestBuffer.position(0);
                        }
                    }
                }
            }
        } finally {
            //if sync, close sockets with replicas since they wont be reused
            if (job.getExecutionType() == ReplicationExecutionType.SYNC) {
                closeReplicaSockets(replicasSockets);
            }
        }
    } finally {
        exitReplicatedLSMComponent(job);
    }
}
Also used : Path(java.nio.file.Path) SocketChannel(java.nio.channels.SocketChannel) LSMComponentProperties(org.apache.asterix.replication.storage.LSMComponentProperties) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) ILSMIndexReplicationJob(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexReplicationJob) ByteBuffer(java.nio.ByteBuffer) ILSMDiskComponent(org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent) Entry(java.util.Map.Entry) RandomAccessFile(java.io.RandomAccessFile) LSMIndexFileProperties(org.apache.asterix.replication.storage.LSMIndexFileProperties) IndexFileProperties(org.apache.asterix.common.storage.IndexFileProperties) ReplicationRequestType(org.apache.asterix.replication.functions.ReplicationProtocol.ReplicationRequestType) LSMIndexFileProperties(org.apache.asterix.replication.storage.LSMIndexFileProperties) Iterator(java.util.Iterator) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 70 with SocketChannel

use of java.nio.channels.SocketChannel in project asterixdb by apache.

the class ReplicaStateChecker method call.

@Override
public Void call() throws Exception {
    Thread.currentThread().setName("ReplicaConnector Thread");
    long startTime = System.currentTimeMillis();
    InetSocketAddress replicaAddress = replica.getAddress(asterixReplicationProperties);
    while (true) {
        try (SocketChannel connection = SocketChannel.open()) {
            connection.configureBlocking(true);
            connection.connect(new InetSocketAddress(replicaAddress.getHostString(), replicaAddress.getPort()));
            ByteBuffer buffer = ReplicationProtocol.getGoodbyeBuffer();
            connection.write(buffer);
            replicationManager.updateReplicaState(replica.getId(), ReplicaState.ACTIVE, suspendReplication);
            return null;
        } catch (IOException | UnresolvedAddressException e) {
            Thread.sleep(WAIT_TIME);
            //check if connection to replica timed out
            if (((System.currentTimeMillis() - startTime) / 1000) >= replicationTimeOut) {
                replicationManager.updateReplicaState(replica.getId(), ReplicaState.DEAD, suspendReplication);
                return null;
            }
        }
    }
}
Also used : SocketChannel(java.nio.channels.SocketChannel) InetSocketAddress(java.net.InetSocketAddress) IOException(java.io.IOException) UnresolvedAddressException(java.nio.channels.UnresolvedAddressException) ByteBuffer(java.nio.ByteBuffer)

Aggregations

SocketChannel (java.nio.channels.SocketChannel)662 IOException (java.io.IOException)298 ServerSocketChannel (java.nio.channels.ServerSocketChannel)285 InetSocketAddress (java.net.InetSocketAddress)202 ByteBuffer (java.nio.ByteBuffer)163 SelectionKey (java.nio.channels.SelectionKey)105 Socket (java.net.Socket)87 Test (org.junit.Test)81 ClosedChannelException (java.nio.channels.ClosedChannelException)50 Selector (java.nio.channels.Selector)42 SocketAddress (java.net.SocketAddress)35 ServerSocket (java.net.ServerSocket)31 ClosedSelectorException (java.nio.channels.ClosedSelectorException)28 CancelledKeyException (java.nio.channels.CancelledKeyException)27 ConnectException (java.net.ConnectException)26 ArrayList (java.util.ArrayList)26 SocketTimeoutException (java.net.SocketTimeoutException)23 SelectableChannel (java.nio.channels.SelectableChannel)21 SocketException (java.net.SocketException)20 HashMap (java.util.HashMap)20