All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zeromq.ZContext Maven / Gradle / Ivy

The newest version!
package org.zeromq;

import java.io.Closeable;
import java.lang.Thread.UncaughtExceptionHandler;
import java.nio.channels.Selector;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Poller;
import org.zeromq.ZMQ.Socket;

import zmq.util.Draft;
import zmq.util.function.BiFunction;

/**
 * ZContext provides a high-level ZeroMQ context management class
 * 

* 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. * */ public class ZContext implements Closeable { /** * Reference to underlying Context object */ private final Context context; /** * List of sockets managed by this ZContext */ private final Set sockets; /** * List of selectors managed by this ZContext */ private final Set selectors; /** * List of ZContext in the shadows */ private final Set shadows; /** * Number of io threads allocated to this context, default 1 */ private final int ioThreads; /** * Indicates if context object is owned by main thread * (useful for multi-threaded applications) */ private final boolean main; /** * Linger timeout, default 0 */ private volatile int linger; /** * Send/receive HWM for pipes */ private int pipehwm; /** * ZMQ_SNDHWM for normal sockets */ private volatile int sndhwm; /** * ZMQ_RCVHWM for normal sockets */ private volatile int rcvhwm; /** * Class Constructor */ public ZContext() { this(1); } public ZContext(int ioThreads) { this(null, ioThreads); } private ZContext(ZContext parent, int ioThreads) { if (parent == null) { this.main = true; this.context = ZMQ.context(ioThreads); this.shadows = Collections.newSetFromMap(new ConcurrentHashMap<>()); } else { this.main = false; this.context = parent.context; this.shadows = parent.shadows; this.shadows.add(this); } // Android compatibility: not using ConcurrentHashMap.newKeySet() this.sockets = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.selectors = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.ioThreads = ioThreads; this.linger = 0; this.pipehwm = 1000; this.sndhwm = 1000; this.rcvhwm = 1000; } /** * Destructor. Call this to gracefully terminate context and close any managed 0MQ sockets */ public void destroy() { for (Socket socket : sockets) { socket.internalClose(); } sockets.clear(); for (Selector selector : selectors) { context.close(selector); } selectors.clear(); // Only terminate context if we are on the main thread if (isMain()) { for (ZContext child : shadows) { child.close(); } context.term(); } else { shadows.remove(this); } } /** * Creates a new managed socket within this ZContext instance. * Use this to get automatic management of the socket at shutdown. *

* The newly created socket will inherited it's linger value from the one * defined for this context. * @param type * socket type * @return * Newly created Socket object */ public Socket createSocket(SocketType type) { // Create and register socket Socket socket = new Socket(this, type); socket.setRcvHWM(this.rcvhwm); socket.setSndHWM(this.sndhwm); socket.setLinger(this.linger); sockets.add(socket); return socket; } /** * @deprecated use {@link #createSocket(SocketType)} * @param type * socket type (see ZMQ static class members) * @return * Newly created Socket object */ @Deprecated public Socket createSocket(int type) { return createSocket(SocketType.type(type)); } /** * Destroys a managed socket within this context and remove * from sockets list. This method should be used only for * fast or emergency close as is set linger instead of using the * socket current value. * @param s {@link org.zeromq.ZMQ.Socket} object to destroy * @deprecated Not to be used any more. {@link org.zeromq.ZMQ.Socket} handle * the close itself. It also override linger settings. */ @Deprecated public void destroySocket(Socket s) { if (s == null) { return; } s.setLinger(linger); try { s.internalClose(); } finally { sockets.remove(s); } } /** * Close managed socket within this context and remove from sockets list. * There is no need to call this method as any {@link Socket} created by * this context will call it on termination. * @param s {@link org.zeromq.ZMQ.Socket} object to destroy */ void closeSocket(Socket s) { if (s == null) { return; } try { s.internalClose(); } finally { sockets.remove(s); } } /** * Creates a selector. It needs to be closed by {@link #closeSelector(Selector)}. * * @return a newly created selector. * @deprecated this was exposed by mistake. */ @Deprecated public Selector createSelector() { return selector(); } /** * Creates a selector. Resource will be released when context will be closed. * * @return a newly created selector. */ Selector selector() { Selector selector = context.selector(); selectors.add(selector); return selector; } /** * Closes a selector. * This is a DRAFT method, and may change without notice. * * @param selector the selector to close. It needs to have been created by {@link #createSelector()}. * @deprecated {@link #createSelector()} was exposed by mistake. while waiting for the API to disappear, this method is provided to allow releasing resources. */ @Deprecated @Draft public void closeSelector(Selector selector) { if (selectors.remove(selector)) { context.close(selector); } } public Poller createPoller(int size) { return new Poller(context, size); } /** * 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 * @deprecated use the instance method directly */ @Deprecated public static ZContext shadow(ZContext ctx) { return ctx.shadow(); } /** * Creates new shadow context. * Shares same underlying org.zeromq.Context instance but has own list * of managed sockets, io thread count etc. * @return New ZContext */ public ZContext shadow() { if (! main) { throw new IllegalStateException("Shadow contexts don't cast shadows"); } ZContext context = new ZContext(this, ioThreads); context.linger = linger; context.sndhwm = sndhwm; context.rcvhwm = rcvhwm; context.pipehwm = pipehwm; return context; } /** * Create an attached thread, An attached thread gets a ctx and a PAIR pipe back to its * parent. It must monitor its pipe, and exit if the pipe becomes unreadable * * @param runnable attached thread * @param args forked runnable args * @return pipe or null if there was an error */ public Socket fork(ZThread.IAttachedRunnable runnable, Object... args) { return ZThread.fork(this, runnable, args); } /** * @return the ioThreads */ public int getIoThreads() { return ioThreads; } /** * A deprecated function that does nothing. * * @param ioThreads the number of ioThreads to set * @deprecated This value should not be changed after the context is initialized. */ @Deprecated public void setIoThreads(int ioThreads) { } /** * @return the default linger for sockets. */ public int getLinger() { return linger; } /** * @param linger the linger that will inherited by created socket. */ public void setLinger(int linger) { this.linger = linger; } /** * Set initial receive HWM for all new normal sockets created in context. * You can set this per-socket after the socket is created. * The default, no matter the underlying ZeroMQ version, is 1,000. * @param rcvhwm the rcvhwm */ public void setRcvHWM(int rcvhwm) { this.rcvhwm = rcvhwm; } /** * Set initial receive HWM for all new normal sockets created in context. * You can set this per-socket after the socket is created. * The default, no matter the underlying ZeroMQ version, is 1,000. * @param sndhwm the sndhwm */ public void setSndHWM(int sndhwm) { this.sndhwm = sndhwm; } /** * Set the handler invoked when a {@link zmq.poll.Poller} abruptly terminates due to an uncaught exception.

* It default to the value of {@link Thread#getDefaultUncaughtExceptionHandler()} * @param handler The object to use as this thread's uncaught exception handler. If null then this thread has no explicit handler. * @throws IllegalStateException If context was already initialized by the creation of a socket */ public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) { context.setUncaughtExceptionHandler(handler); } /** * @return The handler invoked when a {@link zmq.poll.Poller} abruptly terminates due to an uncaught exception. */ public UncaughtExceptionHandler getUncaughtExceptionHandler() { return context.getUncaughtExceptionHandler(); } /** * In {@link zmq.poll.Poller#run()}, some non-fatal exceptions can be thrown. This handler will be notified, so they can * be logged.

* Default to {@link Throwable#printStackTrace()} * @param handler The object to use as this thread's handler for recoverable exceptions notifications. * @throws IllegalStateException If context was already initialized by the creation of a socket */ public void setNotificationExceptionHandler(UncaughtExceptionHandler handler) { context.setNotificationExceptionHandler(handler); } /** * @return The handler invoked when a non-fatal exceptions is thrown in zmq.poll.Poller#run() */ public UncaughtExceptionHandler getNotificationExceptionHandler() { return context.getNotificationExceptionHandler(); } /** * Used to define a custom thread factory. It can be used to create thread that will be bounded to a CPU for * performance or tweaks the created thread. It the UncaughtExceptionHandler is not set, the created thread UncaughtExceptionHandler * will not be changed, so the factory can also be used to set it. * * @param threadFactory the thread factory used by {@link zmq.poll.Poller} * @throws IllegalStateException If context was already initialized by the creation of a socket */ public void setThreadFactor(BiFunction threadFactory) { context.setThreadFactor(threadFactory); } /** * @return the current thread factory */ public BiFunction getThreadFactory() { return context.getThreadFactory(); } /** * @return the main */ public boolean isMain() { return main; } /** * @return true if no shadow context, no sockets and no selectors are alive. */ public boolean isEmpty() { return shadows.isEmpty() && sockets.isEmpty() && selectors.isEmpty(); } /** * @param main whether or not the context is being set to main * @deprecated This value should not be changed after the context is initialized. */ @Deprecated public void setMain(boolean main) { } /** * @return the context */ public Context getContext() { return context; } /** * @param ctx sets the underlying zmq.Context associated with this ZContext wrapper object * @deprecated This value should not be changed after the ZContext is initialized. */ @Deprecated public void setContext(Context ctx) { } /** * Return a copy of the list of currently open sockets. Order is not meaningful. * @return the sockets */ public List getSockets() { return new ArrayList<>(sockets); } @Override public void close() { destroy(); } public boolean isClosed() { return context.isClosed(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy