public void clearAll() { // depth-first for (Map.Entry<String, SubscriptionNode> entry : _children.entrySet()) { entry.getValue().clearAll(); } _subscribers.clear(); }
private void doPrune() { List<SubscriptionNode> trimNodes = new ArrayList<SubscriptionNode>(); _subscriberRoot.prune(trimNodes); while (trimNodes.size() > 0) { SubscriptionNode node = trimNodes.remove(0); SubscriptionNode parent = node.getParent(); if (parent != null) { parent.removeChild(node.getNodeKey()); if (parent.isTrimmable()) { trimNodes.add(parent); } } } }
SubscriptionNode current = locate(record.getSubject(), null, true); assert (current != null); current.addSubscriber(record.getSubscriber()); SubscriptionNode current = locate(record.getSubject(), null, false); if (current != null) current.removeSubscriber(record.getSubscriber(), false); } else { _subscriberRoot.removeSubscriber(record.getSubscriber(), true); _subscriberRoot.clearAll(); break;
@Override public void publish(String senderAddress, String subject, PublishScope scope, Object args) { // publish cannot be in DB transaction, which may hold DB lock too long, and we are guarding this here if (!noDbTxn()){ String errMsg = "NO EVENT PUBLISH CAN BE WRAPPED WITHIN DB TRANSACTION!"; s_logger.error(errMsg, new CloudRuntimeException(errMsg)); } if (_gate.enter(true)) { if (s_logger.isTraceEnabled()) { s_logger.trace("Enter gate in message bus publish"); } try { List<SubscriptionNode> chainFromTop = new ArrayList<SubscriptionNode>(); SubscriptionNode current = locate(subject, chainFromTop, false); if (current != null) current.notifySubscribers(senderAddress, subject, args); Collections.reverse(chainFromTop); for (SubscriptionNode node : chainFromTop) node.notifySubscribers(senderAddress, subject, args); } finally { _gate.leave(); } } }
@Override public void subscribe(String subject, MessageSubscriber subscriber) { assert (subject != null); assert (subscriber != null); if (_gate.enter()) { if (s_logger.isTraceEnabled()) { s_logger.trace("Enter gate in message bus subscribe"); } try { SubscriptionNode current = locate(subject, null, true); assert (current != null); current.addSubscriber(subscriber); } finally { _gate.leave(); } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Subscribe, subject, subscriber)); } } }
@Override public void clearAll() { if (_gate.enter()) { if (s_logger.isTraceEnabled()) { s_logger.trace("Enter gate in message bus clearAll"); } try { _subscriberRoot.clearAll(); doPrune(); } finally { _gate.leave(); } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.ClearAll, null, null)); } } }
private static SubscriptionNode locate(String[] subjectPathTokens, SubscriptionNode current, List<SubscriptionNode> chainFromTop, boolean createPath) { assert (current != null); assert (subjectPathTokens != null); assert (subjectPathTokens.length > 0); if (chainFromTop != null) chainFromTop.add(current); SubscriptionNode next = current.getChild(subjectPathTokens[0]); if (next == null) { if (createPath) { next = new SubscriptionNode(current, subjectPathTokens[0], null); current.addChild(subjectPathTokens[0], next); } else { return null; } } if (subjectPathTokens.length > 1) { return locate(Arrays.copyOfRange(subjectPathTokens, 1, subjectPathTokens.length), next, chainFromTop, createPath); } else { return next; } }
public MessageBusBase() { _gate = new Gate(); _pendingActions = new ArrayList<ActionRecord>(); _subscriberRoot = new SubscriptionNode(null, "/", null); }
public void prune(List<SubscriptionNode> trimNodes) { assert (trimNodes != null); for (Map.Entry<String, SubscriptionNode> entry : _children.entrySet()) { entry.getValue().prune(trimNodes); } if (isTrimmable()) trimNodes.add(this); }