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);
}
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);
}
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;
}
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;
}
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;
}
Aggregations