Search in sources :

Example 1 with PollItem

use of zmq.poll.PollItem in project jeromq by zeromq.

the class InprocDisconnectTest method testDisconnectInproc.

private void testDisconnectInproc(Ctx context, Selector selector) throws Exception {
    int publicationsReceived = 0;
    boolean isSubscribed = false;
    SocketBase pubSocket = ZMQ.socket(context, ZMQ.ZMQ_XPUB);
    SocketBase subSocket = ZMQ.socket(context, ZMQ.ZMQ_SUB);
    ZMQ.setSocketOption(subSocket, ZMQ.ZMQ_SUBSCRIBE, "foo".getBytes());
    ZMQ.bind(pubSocket, "inproc://someInProcDescriptor");
    int more;
    int iteration = 0;
    while (true) {
        PollItem[] items = { // read publications
        new PollItem(subSocket, ZMQ.ZMQ_POLLIN), // read subscriptions
        new PollItem(pubSocket, ZMQ.ZMQ_POLLIN) };
        int rc = ZMQ.poll(selector, items, 2, 100L);
        if (items[1].isReadable()) {
            while (true) {
                Msg msg = ZMQ.recv(pubSocket, 0);
                int msgSize = msg.size();
                byte[] buffer = msg.data();
                if (buffer[0] == 0) {
                    assertTrue(isSubscribed);
                    System.out.printf("unsubscribing from '%s'\n", new String(buffer, 1, msgSize - 1));
                    isSubscribed = false;
                } else {
                    assert (!isSubscribed);
                    System.out.printf("subscribing on '%s'\n", new String(buffer, 1, msgSize - 1));
                    isSubscribed = true;
                }
                more = ZMQ.getSocketOption(pubSocket, ZMQ.ZMQ_RCVMORE);
                if (more == 0) {
                    // Last message part
                    break;
                }
            }
        }
        if (items[0].isReadable()) {
            while (true) {
                Msg msg = ZMQ.recv(subSocket, 0);
                int msgSize = msg.size();
                byte[] buffer = msg.data();
                System.out.printf("received on subscriber '%s'\n", new String(buffer, 0, msgSize));
                more = ZMQ.getSocketOption(subSocket, ZMQ.ZMQ_RCVMORE);
                if (more == 0) {
                    publicationsReceived++;
                    // Last message part
                    break;
                }
            }
        }
        if (iteration == 1) {
            ZMQ.connect(subSocket, "inproc://someInProcDescriptor");
        }
        if (iteration == 4) {
            ZMQ.disconnect(subSocket, "inproc://someInProcDescriptor");
        }
        if (iteration > 4 && rc == 0) {
            break;
        }
        Msg channelEnvlp = new Msg("foo".getBytes(ZMQ.CHARSET));
        ZMQ.sendMsg(pubSocket, channelEnvlp, ZMQ.ZMQ_SNDMORE);
        Msg message = new Msg("this is foo!".getBytes(ZMQ.CHARSET));
        ZMQ.sendMsg(pubSocket, message, 0);
        iteration++;
    }
    assertEquals(3, publicationsReceived);
    assertFalse(isSubscribed);
    ZMQ.close(pubSocket);
    ZMQ.close(subSocket);
}
Also used : PollItem(zmq.poll.PollItem)

Example 2 with PollItem

use of zmq.poll.PollItem in project jeromq by zeromq.

the class PollTest method assertPoller.

private <T extends SelectableChannel> void assertPoller(T in, T out, TxRx<Integer> tx, TxRx<Object> rx) throws IOException {
    Ctx context = ZMQ.init(1);
    assertThat(context, notNullValue());
    Selector selector = context.createSelector();
    assertThat(selector, notNullValue());
    PollItem[] items = new PollItem[2];
    items[0] = new PollItem(out, ZMQ.ZMQ_POLLOUT);
    items[1] = new PollItem(in, ZMQ.ZMQ_POLLIN);
    String payload = UUID.randomUUID().toString();
    boolean sending = true;
    while (true) {
        int events = ZMQ.poll(selector, items, 1000);
        if (events < 0) {
            fail("unable to poll events");
        }
        if (sending && items[0].isWritable()) {
            sending = false;
            ByteBuffer bb = ByteBuffer.allocate(payload.length());
            bb.put(payload.getBytes());
            bb.flip();
            int written = tx.apply(bb);
            assertThat(written, is(payload.length()));
        }
        if (!sending && items[1].isReadable()) {
            ByteBuffer bb = ByteBuffer.allocate(payload.length());
            rx.apply(bb);
            String read = new String(bb.array(), 0, bb.limit());
            assertThat(read, is(payload));
            break;
        }
    }
    context.closeSelector(selector);
    ZMQ.term(context);
}
Also used : PollItem(zmq.poll.PollItem) ByteBuffer(java.nio.ByteBuffer) Selector(java.nio.channels.Selector)

Example 3 with PollItem

use of zmq.poll.PollItem in project jeromq by zeromq.

the class ZMQ method poll.

/**
 * Polling on items with given selector
 * CAUTION: This could be affected by jdk epoll bug
 *
 * @param selector Open and reuse this selector and do not forget to close when it is not used.
 * @param items
 * @param count
 * @param timeout
 * @return number of events
 */
public static int poll(Selector selector, PollItem[] items, int count, long timeout) {
    Utils.checkArgument(items != null, "items have to be supplied for polling");
    if (count == 0) {
        if (timeout <= 0) {
            return 0;
        }
        LockSupport.parkNanos(TimeUnit.NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS));
        return 0;
    }
    long now = 0L;
    long end = 0L;
    HashMap<SelectableChannel, SelectionKey> saved = new HashMap<SelectableChannel, SelectionKey>();
    for (SelectionKey key : selector.keys()) {
        if (key.isValid()) {
            saved.put(key.channel(), key);
        }
    }
    for (int i = 0; i < count; i++) {
        PollItem item = items[i];
        if (item == null) {
            continue;
        }
        // mailbox channel if ZMQ socket
        SelectableChannel ch = item.getChannel();
        SelectionKey key = saved.remove(ch);
        if (key != null) {
            if (key.interestOps() != item.interestOps()) {
                key.interestOps(item.interestOps());
            }
            key.attach(item);
        } else {
            try {
                ch.register(selector, item.interestOps(), item);
            } catch (ClosedSelectorException e) {
                // context was closed asynchronously, exit gracefully
                return -1;
            } catch (ClosedChannelException e) {
                throw new ZError.IOException(e);
            }
        }
    }
    if (!saved.isEmpty()) {
        for (SelectionKey deprecated : saved.values()) {
            deprecated.cancel();
        }
    }
    boolean firstPass = true;
    int nevents = 0;
    int ready;
    while (true) {
        // Compute the timeout for the subsequent poll.
        long waitMillis;
        if (firstPass) {
            waitMillis = 0L;
        } else if (timeout < 0L) {
            waitMillis = -1L;
        } else {
            waitMillis = TimeUnit.NANOSECONDS.toMillis(end - now);
            if (waitMillis == 0) {
                waitMillis = 1L;
            }
        }
        // Wait for events.
        try {
            int rc;
            if (waitMillis < 0) {
                rc = selector.select(0);
            } else if (waitMillis == 0) {
                rc = selector.selectNow();
            } else {
                rc = selector.select(waitMillis);
            }
            for (SelectionKey key : selector.keys()) {
                PollItem item = (PollItem) key.attachment();
                ready = item.readyOps(key, rc);
                if (ready < 0) {
                    return -1;
                }
                if (ready > 0) {
                    nevents++;
                }
            }
            selector.selectedKeys().clear();
        } catch (ClosedSelectorException e) {
            // context was closed asynchronously, exit gracefully
            return -1;
        } catch (IOException e) {
            throw new ZError.IOException(e);
        }
        // If timeout is zero, exit immediately whether there are events or not.
        if (timeout == 0) {
            break;
        }
        if (nevents > 0) {
            break;
        }
        // If timeout is infinite we can just loop until we get some events.
        if (timeout < 0) {
            if (firstPass) {
                firstPass = false;
            }
            continue;
        }
        // when the polling should time out.
        if (firstPass) {
            now = Clock.nowNS();
            end = now + TimeUnit.MILLISECONDS.toNanos(timeout);
            if (now == end) {
                break;
            }
            firstPass = false;
            continue;
        }
        // Find out whether timeout have expired.
        now = Clock.nowNS();
        if (now >= end) {
            break;
        }
    }
    return nevents;
}
Also used : SelectionKey(java.nio.channels.SelectionKey) ClosedChannelException(java.nio.channels.ClosedChannelException) PollItem(zmq.poll.PollItem) HashMap(java.util.HashMap) IOException(java.io.IOException) SelectableChannel(java.nio.channels.SelectableChannel) ClosedSelectorException(java.nio.channels.ClosedSelectorException)

Example 4 with PollItem

use of zmq.poll.PollItem in project jeromq by zeromq.

the class Proxy method start.

private boolean start(SocketBase frontend, SocketBase backend, SocketBase capture, SocketBase control) {
    // The algorithm below assumes ratio of requests and replies processed
    // under full load to be 1:1.
    // TODO: The current implementation drops messages when
    // any of the pipes becomes full.
    int rc;
    int more;
    Msg msg;
    int count = control == null ? 2 : 3;
    PollItem[] items = new PollItem[count];
    items[0] = new PollItem(frontend, ZMQ.ZMQ_POLLIN);
    items[1] = new PollItem(backend, ZMQ.ZMQ_POLLIN);
    if (control != null) {
        items[2] = new PollItem(control, ZMQ.ZMQ_POLLIN);
    }
    PollItem[] itemsout = new PollItem[2];
    itemsout[0] = new PollItem(frontend, ZMQ.ZMQ_POLLOUT);
    itemsout[1] = new PollItem(backend, ZMQ.ZMQ_POLLOUT);
    Selector selector = frontend.getCtx().createSelector();
    try {
        while (state != State.TERMINATED) {
            // Wait while there are either requests or replies to process.
            rc = ZMQ.poll(selector, items, -1);
            if (rc < 0) {
                return false;
            }
            // POLLOUT is only checked when frontend and backend sockets are not the same.
            if (frontend != backend) {
                rc = ZMQ.poll(selector, itemsout, 0L);
                if (rc < 0) {
                    return false;
                }
            }
            // Process a control command if any
            if (control != null && items[2].isReadable()) {
                msg = control.recv(0);
                if (msg == null) {
                    return false;
                }
                more = control.getSocketOpt(ZMQ.ZMQ_RCVMORE);
                if (more < 0) {
                    return false;
                }
                // Copy message to capture socket if any
                boolean success = capture(capture, msg, more);
                if (!success) {
                    return false;
                }
                byte[] command = msg.data();
                if (Arrays.equals(command, ZMQ.PROXY_PAUSE)) {
                    state = State.PAUSED;
                } else if (Arrays.equals(command, ZMQ.PROXY_RESUME)) {
                    state = State.ACTIVE;
                } else if (Arrays.equals(command, ZMQ.PROXY_TERMINATE)) {
                    state = State.TERMINATED;
                } else {
                    // This is an API error, we should assert
                    System.out.printf("E: invalid command sent to proxy '%s'%n", new String(command, ZMQ.CHARSET));
                    assert false;
                }
            }
            // Process a request.
            if (process(items[0], itemsout[1], frontend, backend)) {
                if (!forward(frontend, backend, capture)) {
                    return false;
                }
            }
            // Process a reply.
            if (process(items[1], itemsout[0], frontend, backend)) {
                if (!forward(backend, frontend, capture)) {
                    return false;
                }
            }
        }
    } finally {
        frontend.getCtx().closeSelector(selector);
    }
    return true;
}
Also used : PollItem(zmq.poll.PollItem) Selector(java.nio.channels.Selector)

Example 5 with PollItem

use of zmq.poll.PollItem in project jeromq by zeromq.

the class ZPoller method filter.

// filters items to get the first one matching the criteria, or null if none found
protected PollItem filter(final Object socketOrChannel, int events) {
    if (socketOrChannel == null) {
        return null;
    }
    CompositePollItem item = items.get(socketOrChannel);
    if (item == null) {
        return null;
    }
    PollItem pollItem = item.item();
    if (pollItem == null) {
        return null;
    }
    if (pollItem.hasEvent(events)) {
        return pollItem;
    }
    return null;
}
Also used : PollItem(zmq.poll.PollItem)

Aggregations

PollItem (zmq.poll.PollItem)6 SelectableChannel (java.nio.channels.SelectableChannel)2 Selector (java.nio.channels.Selector)2 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 ClosedSelectorException (java.nio.channels.ClosedSelectorException)1 SelectionKey (java.nio.channels.SelectionKey)1 HashMap (java.util.HashMap)1 Socket (org.zeromq.ZMQ.Socket)1