public <T> void publish(final SensorEvent<T> event) { // REVIEW 1459 - execution // delivery in parallel/background, using execution manager // subscriptions, should define SingleThreadedScheduler for any subscriber ID tag // in order to ensure callbacks are invoked in the order they are submitted // (recommend exactly one per subscription to prevent deadlock) // this is done with: // em.setTaskSchedulerForTag(subscriberId, SingleThreadedScheduler.class); // note, generating the notifications must be done in the calling thread to preserve order // e.g. emit(A); emit(B); should cause onEvent(A); onEvent(B) in that order if (LOG.isTraceEnabled()) LOG.trace("{} got a {} event", this, event); totalEventsPublishedCount.incrementAndGet(); Set<Subscription> subs = (Set<Subscription>) ((Set<?>) getSubscriptionsForEntitySensor(event.getSource(), event.getSensor())); if (groovyTruth(subs)) { if (LOG.isTraceEnabled()) LOG.trace( "sending {}, {} to {}", new Object[] {event.getSensor().getName(), event, join(subs, ",")}); for (Subscription s : subs) { if (s.eventFilter != null && !s.eventFilter.apply(event)) continue; final Subscription sAtClosureCreation = s; em.submit( mapOf("tag", s.subscriberExecutionManagerTag), new Runnable() { public void run() { sAtClosureCreation.listener.onEvent(event); } }); totalEventsDeliveredCount.incrementAndGet(); } } }
static Object makeEntitySensorToken(SensorEvent<?> se) { return makeEntitySensorToken(se.getSource(), se.getSensor()); }