@Override public void prune() { if (_gate.enter()) { if (s_logger.isTraceEnabled()) { s_logger.trace("Enter gate in message bus prune"); } try { doPrune(); } finally { _gate.leave(); } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Prune, null, null)); } } }
private SubscriptionNode locate(String subject, List<SubscriptionNode> chainFromTop, boolean createPath) { assert (subject != null); // "/" is special name for root node if (subject.equals("/")) return _subscriberRoot; String[] subjectPathTokens = subject.split("\\."); return locate(subjectPathTokens, _subscriberRoot, chainFromTop, createPath); }
@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(); } } }
switch (record.getType()) { case Subscribe: { 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); doPrune(); break;
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; } }
@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)); } } }
@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 unsubscribe(String subject, MessageSubscriber subscriber) { if (_gate.enter()) { if (s_logger.isTraceEnabled()) { s_logger.trace("Enter gate in message bus unsubscribe"); } try { if (subject != null) { SubscriptionNode current = locate(subject, null, false); if (current != null) current.removeSubscriber(subscriber, false); } else { _subscriberRoot.removeSubscriber(subscriber, true); } } finally { _gate.leave(); } } else { synchronized (_pendingActions) { _pendingActions.add(new ActionRecord(ActionType.Unsubscribe, subject, subscriber)); } } }