Search in sources :

Example 1 with Pipe

use of zmq.pipe.Pipe in project jeromq by zeromq.

the class Server method xrecv.

@Override
protected Msg xrecv() {
    Msg msg;
    ValueReference<Pipe> pipe = new ValueReference<>();
    msg = fq.recvPipe(errno, pipe);
    // Drop any messages with more flag
    while (msg != null && msg.hasMore()) {
        // drop all frames of the current multi-frame message
        msg = fq.recvPipe(errno, null);
        while (msg != null && msg.hasMore()) {
            msg = fq.recvPipe(errno, null);
        }
        // get the new message
        if (msg != null) {
            msg = fq.recvPipe(errno, pipe);
        }
    }
    if (msg == null) {
        return msg;
    }
    assert (pipe.get() != null);
    int routingId = pipe.get().getRoutingId();
    msg.setRoutingId(routingId);
    return msg;
}
Also used : Msg(zmq.Msg) Pipe(zmq.pipe.Pipe) ValueReference(zmq.util.ValueReference)

Example 2 with Pipe

use of zmq.pipe.Pipe in project jeromq by zeromq.

the class Req method recvReplyPipe.

private Msg recvReplyPipe() {
    while (true) {
        ValueReference<Pipe> pipe = new ValueReference<>();
        Msg msg = super.recvpipe(pipe);
        if (msg == null) {
            return null;
        }
        if (replyPipe.get() == null || replyPipe.get() == pipe.get()) {
            return msg;
        }
    }
}
Also used : Msg(zmq.Msg) Pipe(zmq.pipe.Pipe) ValueReference(zmq.util.ValueReference)

Example 3 with Pipe

use of zmq.pipe.Pipe in project jeromq by zeromq.

the class FQ method recvPipe.

public Msg recvPipe(Errno errno, ValueReference<Pipe> pipe) {
    // Round-robin over the pipes to get the next message.
    while (active > 0) {
        // Try to fetch new message. If we've already read part of the message
        // subsequent part should be immediately available.
        final Pipe currentPipe = pipes.get(current);
        final Msg msg = currentPipe.read();
        final boolean fetched = msg != null;
        // the 'current' pointer.
        if (fetched) {
            if (pipe != null) {
                pipe.set(currentPipe);
            }
            more = msg.hasMore();
            if (!more) {
                lastIn = currentPipe;
                // happens when multiple threads receive messages
                assert (active > 0);
                current = (current + 1) % active;
            }
            return msg;
        }
        // we should get the remaining parts without blocking.
        assert (!more);
        active--;
        Collections.swap(pipes, current, active);
        if (current == active) {
            current = 0;
        }
    }
    // No message is available. Initialize the output parameter
    // to be a 0-byte message.
    errno.set(ZError.EAGAIN);
    return null;
}
Also used : Msg(zmq.Msg) Pipe(zmq.pipe.Pipe)

Example 4 with Pipe

use of zmq.pipe.Pipe in project jeromq by zeromq.

the class SocketBase method connectInternal.

private boolean connectInternal(String addr) {
    if (ctxTerminated) {
        errno.set(ZError.ETERM);
        return false;
    }
    options.mechanism.check(options);
    // Process pending commands, if any.
    boolean brc = processCommands(0, false, null);
    if (!brc) {
        return false;
    }
    SimpleURI uri = SimpleURI.create(addr);
    String address = uri.getAddress();
    NetProtocol protocol = checkProtocol(uri.getProtocol());
    if (protocol == null || !protocol.valid) {
        return false;
    }
    if (protocol == NetProtocol.inproc) {
        // TODO: inproc connect is specific with respect to creating pipes
        // as there's no 'reconnect' functionality implemented. Once that
        // is in place we should follow generic pipe creation algorithm.
        // Find the peer endpoint.
        Ctx.Endpoint peer = findEndpoint(addr);
        // The total HWM for an inproc connection should be the sum of
        // the binder's HWM and the connector's HWM.
        int sndhwm = 0;
        if (peer.socket == null) {
            sndhwm = options.sendHwm;
        } else if (options.sendHwm != 0 && peer.options.recvHwm != 0) {
            sndhwm = options.sendHwm + peer.options.recvHwm;
        }
        int rcvhwm = 0;
        if (peer.socket == null) {
            rcvhwm = options.recvHwm;
        } else if (options.recvHwm != 0 && peer.options.sendHwm != 0) {
            rcvhwm = options.recvHwm + peer.options.sendHwm;
        }
        // Create a bi-directional pipe to connect the peers.
        ZObject[] parents = { this, peer.socket == null ? this : peer.socket };
        boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
        int[] hwms = { conflate ? -1 : sndhwm, conflate ? -1 : rcvhwm };
        boolean[] conflates = { conflate, conflate };
        Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
        // Attach local end of the pipe to this socket object.
        attachPipe(pipes[0], true);
        if (peer.socket == null) {
            // The peer doesn't exist yet so we don't know whether
            // to send the identity message or not. To resolve this,
            // we always send our identity and drop it later if
            // the peer doesn't expect it.
            Msg id = new Msg(options.identitySize);
            id.put(options.identity, 0, options.identitySize);
            id.setFlags(Msg.IDENTITY);
            boolean written = pipes[0].write(id);
            assert (written);
            pipes[0].flush();
            // If set, send the hello msg of the local socket to the peer.
            if (options.canSendHelloMsg && options.helloMsg != null) {
                written = pipes[0].write(options.helloMsg);
                assert (written);
                pipes[0].flush();
            }
            pendConnection(addr, new Ctx.Endpoint(this, options), pipes);
        } else {
            // If required, send the identity of the peer to the local socket.
            if (peer.options.recvIdentity) {
                Msg id = new Msg(options.identitySize);
                id.put(options.identity, 0, options.identitySize);
                id.setFlags(Msg.IDENTITY);
                boolean written = pipes[0].write(id);
                assert (written);
                pipes[0].flush();
            }
            // If required, send the identity of the local socket to the peer.
            if (options.recvIdentity) {
                Msg id = new Msg(peer.options.identitySize);
                id.put(peer.options.identity, 0, peer.options.identitySize);
                id.setFlags(Msg.IDENTITY);
                boolean written = pipes[1].write(id);
                assert (written);
                pipes[1].flush();
            }
            // If set, send the hello msg of the local socket to the peer.
            if (options.canSendHelloMsg && options.helloMsg != null) {
                boolean written = pipes[0].write(options.helloMsg);
                assert (written);
                pipes[0].flush();
            }
            // If set, send the hello msg of the peer to the local socket.
            if (peer.options.canSendHelloMsg && peer.options.helloMsg != null) {
                boolean written = pipes[1].write(peer.options.helloMsg);
                assert (written);
                pipes[1].flush();
            }
            if (peer.options.canReceiveDisconnectMsg && peer.options.disconnectMsg != null) {
                pipes[0].setDisconnectMsg(peer.options.disconnectMsg);
            }
            // Attach remote end of the pipe to the peer socket. Note that peer's
            // seqnum was incremented in findEndpoint function. We don't need it
            // increased here.
            sendBind(peer.socket, pipes[1], false);
        }
        // Save last endpoint URI
        options.lastEndpoint = addr;
        // remember inproc connections for disconnect
        inprocs.insert(addr, pipes[0]);
        return true;
    }
    boolean isSingleConnect = options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_SUB || options.type == ZMQ.ZMQ_REQ;
    if (isSingleConnect) {
        if (endpoints.hasValues(addr)) {
            // nonsensical results.
            return true;
        }
    }
    // Choose the I/O thread to run the session in.
    IOThread ioThread = chooseIoThread(options.affinity);
    if (ioThread == null) {
        errno.set(ZError.EMTHREAD);
        return false;
    }
    Address paddr = new Address(protocol, address);
    // Resolve address (if needed by the protocol)
    protocol.resolve(paddr, options.ipv6);
    // Create session.
    SessionBase session = Sockets.createSession(ioThread, true, this, options, paddr);
    assert (session != null);
    // PGM does not support subscription forwarding; ask for all data to be
    // sent to this pipe. (same for NORM, currently?)
    boolean subscribe2all = protocol.subscribe2all;
    Pipe newpipe = null;
    if (options.immediate || subscribe2all) {
        // Create a bi-directional pipe.
        ZObject[] parents = { this, session };
        boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
        int[] hwms = { conflate ? -1 : options.sendHwm, conflate ? -1 : options.recvHwm };
        boolean[] conflates = { conflate, conflate };
        Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
        // Attach local end of the pipe to the socket object.
        attachPipe(pipes[0], subscribe2all, true);
        newpipe = pipes[0];
        // Attach remote end of the pipe to the session object later on.
        session.attachPipe(pipes[1]);
    }
    // Save last endpoint URI
    options.lastEndpoint = paddr.toString();
    addEndpoint(addr, session, newpipe);
    return true;
}
Also used : Address(zmq.io.net.Address) IZAddress(zmq.io.net.Address.IZAddress) InetSocketAddress(java.net.InetSocketAddress) Pipe(zmq.pipe.Pipe) SessionBase(zmq.io.SessionBase) IOThread(zmq.io.IOThread) NetProtocol(zmq.io.net.NetProtocol)

Example 5 with Pipe

use of zmq.pipe.Pipe in project jeromq by zeromq.

the class SocketBase method termEndpoint.

public final boolean termEndpoint(String addr) {
    lock();
    try {
        // Check whether the library haven't been shut down yet.
        if (ctxTerminated) {
            errno.set(ZError.ETERM);
            return false;
        }
        // Check whether endpoint address passed to the function is valid.
        if (addr == null) {
            errno.set(ZError.EINVAL);
            return false;
        }
        // Process pending commands, if any, since there could be pending unprocessed processOwn()'s
        // (from launchChild() for example) we're asked to terminate now.
        boolean rc = processCommands(0, false, null);
        if (!rc) {
            return false;
        }
        SimpleURI uri = SimpleURI.create(addr);
        NetProtocol protocol = checkProtocol(uri.getProtocol());
        if (protocol == null) {
            return false;
        }
        // Disconnect an inproc socket
        if (protocol == NetProtocol.inproc) {
            if (unregisterEndpoint(addr, this)) {
                return true;
            }
            Collection<Pipe> olds = inprocs.remove(addr);
            if (olds == null || olds.isEmpty()) {
                errno.set(ZError.ENOENT);
                return false;
            } else {
                for (Pipe old : olds) {
                    old.sendDisconnectMsg();
                    old.terminate(true);
                }
            }
            return true;
        }
        String resolvedAddress = addr;
        // socket is connected or bound, try with both.
        if (protocol == NetProtocol.tcp) {
            boolean endpoint = endpoints.hasValues(resolvedAddress);
            if (!endpoint) {
                // TODO V4 resolve TCP address when unbinding
                IZAddress address = protocol.zresolve(uri.getAddress(), options.ipv6);
                resolvedAddress = address.address().toString();
                endpoint = endpoints.hasValues(resolvedAddress);
                if (!endpoint) {
                    // no luck, try with local resolution
                    InetSocketAddress socketAddress = address.resolve(uri.getAddress(), options.ipv6, true);
                    resolvedAddress = socketAddress.toString();
                }
            }
        }
        // Find the endpoints range (if any) corresponding to the addr_ string.
        Collection<EndpointPipe> eps = endpoints.remove(resolvedAddress);
        if (eps == null || eps.isEmpty()) {
            errno.set(ZError.ENOENT);
            return false;
        } else {
            // If we have an associated pipe, terminate it.
            for (EndpointPipe ep : eps) {
                if (ep.pipe != null) {
                    ep.pipe.terminate(false);
                }
                termChild(ep.endpoint);
            }
        }
        return true;
    } finally {
        unlock();
    }
}
Also used : InetSocketAddress(java.net.InetSocketAddress) NetProtocol(zmq.io.net.NetProtocol) Pipe(zmq.pipe.Pipe) IZAddress(zmq.io.net.Address.IZAddress)

Aggregations

Pipe (zmq.pipe.Pipe)20 Msg (zmq.Msg)13 Test (org.junit.Test)6 ValueReference (zmq.util.ValueReference)6 Blob (zmq.util.Blob)4 InetSocketAddress (java.net.InetSocketAddress)2 ZObject (zmq.ZObject)2 Metadata (zmq.io.Metadata)2 IZAddress (zmq.io.net.Address.IZAddress)2 NetProtocol (zmq.io.net.NetProtocol)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Ctx (zmq.Ctx)1 IOThread (zmq.io.IOThread)1 SessionBase (zmq.io.SessionBase)1 Address (zmq.io.net.Address)1