zmq.LB Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jeromq Show documentation
Show all versions of jeromq Show documentation
Pure Java implementation of libzmq
package zmq;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class LB
{
// List of outbound pipes.
private final List pipes;
// Number of active pipes. All the active pipes are located at the
// beginning of the pipes array.
private int active;
// Points to the last pipe that the most recent message was sent to.
private int current;
// True if last we are in the middle of a multipart message.
private boolean more;
// True if we are dropping current message.
private boolean dropping;
public LB()
{
active = 0;
current = 0;
more = false;
dropping = false;
pipes = new ArrayList();
}
public void attach(Pipe pipe)
{
pipes.add(pipe);
activated(pipe);
}
public void terminated(Pipe pipe)
{
int index = pipes.indexOf(pipe);
// If we are in the middle of multipart message and current pipe
// have disconnected, we have to drop the remainder of the message.
if (index == current && more) {
dropping = true;
}
// Remove the pipe from the list; adjust number of active pipes
// accordingly.
if (index < active) {
active--;
Collections.swap(pipes, index, active);
if (current == active) {
current = 0;
}
}
pipes.remove(pipe);
}
public void activated(Pipe pipe)
{
// Move the pipe to the list of active pipes.
Collections.swap(pipes, pipes.indexOf(pipe), active);
active++;
}
public boolean send(Msg msg, ValueReference errno)
{
// Drop the message if required. If we are at the end of the message
// switch back to non-dropping mode.
if (dropping) {
more = msg.hasMore();
dropping = more;
// msg_.close();
return true;
}
while (active > 0) {
if (pipes.get(current).write(msg)) {
break;
}
assert (!more);
active--;
if (current < active) {
Collections.swap(pipes, current, active);
}
else {
current = 0;
}
}
// If there are no pipes we cannot send the message.
if (active == 0) {
errno.set(ZError.EAGAIN);
return false;
}
// If it's final part of the message we can flush it downstream and
// continue round-robining (load balance).
more = msg.hasMore();
if (!more) {
pipes.get(current).flush();
if (++current >= active) {
current = 0;
}
}
return true;
}
public boolean hasOut()
{
// If one part of the message was already written we can definitely
// write the rest of the message.
if (more) {
return true;
}
while (active > 0) {
// Check whether a pipe has room for another message.
if (pipes.get(current).checkWrite()) {
return true;
}
// Deactivate the pipe.
active--;
Collections.swap(pipes, current, active);
if (current == active) {
current = 0;
}
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy