org.zeromq.ZContext Maven / Gradle / Ivy
package org.zeromq;
import java.io.Closeable;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;
/**
* ZContext provides a high-level ZeroMQ context management class
*
* The ZContext class wraps java org.zeromq.Context objects, which in turn wrap native 0MQ contexts. It manages open
* sockets in the context and automatically closes these before terminating the context. It provides a simple way to set
* the linger timeout on sockets, and configure contexts for number of I/O threads. Sets-up signal (interrupt) handling
* for the process.
*
* @see czmq version
*
* @author rsmith (at) rsbatechnology (dot) co (dot) uk
*/
public class ZContext implements Closeable {
/**
* Reference to underlying Context object
*/
private ZMQ.Context context;
/**
* List of sockets managed by this ZContext
*/
private List sockets;
/**
* Number of io threads allocated to this context, default 1
*/
private int ioThreads;
/**
* Linger timeout, default 0
*/
private int linger;
/**
* Indicates if context object is owned by main thread (useful for multi-threaded applications)
*/
private boolean main;
/**
* Class Constructor
*/
public ZContext() {
context = null; // Don't create Context until create 1st 0MQ socket
sockets = new CopyOnWriteArrayList();
ioThreads = 1;
linger = 0;
main = true;
}
/**
* Destructor. Call this to gracefully terminate context and close any managed 0MQ sockets
*/
public void destroy() {
ListIterator itr = sockets.listIterator();
while (itr.hasNext()) {
destroySocket(itr.next());
}
sockets.clear();
// Only terminate context if we are on the main thread
if (isMain() && context != null)
context.term();
}
/**
* Creates a new managed socket within this ZContext instance. Use this to get automatic management of the socket at
* shutdown
*
* @param type socket type (see ZMQ static class members)
* @return Newly created Socket object
*/
public Socket createSocket(int type) {
if (context == null)
context = ZMQ.context(ioThreads);
// Create and register socket
Socket socket = context.socket(type);
sockets.add(socket);
return socket;
}
/**
* Destroys managed socket within this context and remove from sockets list
*
* @param s org.zeromq.Socket object to destroy
*/
public void destroySocket(Socket s) {
if (s == null)
return;
if (sockets.contains(s)) {
try {
s.setLinger(linger);
} catch (ZMQException e) {
if (e.getErrorCode() != ZMQ.ETERM()) {
throw e;
}
}
s.close();
sockets.remove(s);
}
}
/**
* Creates new shadow context. Shares same underlying org.zeromq.Context instance but has own list of managed
* sockets, io thread count etc.
*
* @param ctx Original ZContext to create shadow of
* @return New ZContext
*/
public static ZContext shadow(ZContext ctx) {
ZContext shadow = new ZContext();
shadow.setContext(ctx.getContext());
shadow.setMain(false);
return shadow;
}
/**
* @return the ioThreads
*/
public int getIoThreads() {
return ioThreads;
}
/**
* @param ioThreads the ioThreads to set
*/
public void setIoThreads(int ioThreads) {
this.ioThreads = ioThreads;
}
/**
* @return the linger
*/
public int getLinger() {
return linger;
}
/**
* @param linger the linger to set
*/
public void setLinger(int linger) {
this.linger = linger;
}
/**
* @return the main
*/
public boolean isMain() {
return main;
}
/**
* @param main the main to set
*/
public void setMain(boolean main) {
this.main = main;
}
/**
* @return the context
*/
public Context getContext() {
return context;
}
/**
* @param ctx sets the underlying org.zeromq.Context associated with this ZContext wrapper object
*/
public void setContext(Context ctx) {
this.context = ctx;
}
/**
* @return the sockets
*/
public List getSockets() {
return sockets;
}
@Override
public void close() {
destroy();
}
}