private BroadcasterTracker track(AtmosphereResource r) { BroadcasterTracker tracker = states.get(r.uuid()); if (tracker == null) { tracker = new BroadcasterTracker(); states.put(r.uuid(), tracker); logger.trace("AtmosphereResource {} state now tracked", r.uuid()); } return tracker; }
@Override public void run() { long now = System.currentTimeMillis(); for (Map.Entry<String, BroadcasterTracker> t : states.entrySet()) { // The resource may still be suspended but we don't want to keep a reference to it, so we swap // the state and will recover. if (now - t.getValue().lastTick() > timeout) { logger.trace("AtmosphereResource {} state destroyed.", t.getKey()); states.remove(t.getKey()); } } } }, timeout, timeout, TimeUnit.MILLISECONDS);
final BroadcasterTracker tracker = track(r).tick();
for (String broadcasterID : tracker.ids()) { Broadcaster b = factory.lookup(broadcasterID, false); logger.trace("About to associate resource {} with Broadcaster {}", r.uuid(), broadcasterID);
public List<Object> retrieveCache(AtmosphereResource r, BroadcasterTracker tracker, boolean force) { List<Object> cachedMessages = new LinkedList<Object>(); for (String broadcasterID : tracker.ids()) { Broadcaster b = factory.lookup(broadcasterID, false); BroadcasterCache cache; logger.trace("About to retrieve cached messages for resource {} with Broadcaster {}, tracked by " + b, r.uuid(), r.getBroadcaster()); if (b != null && (force || !b.getID().equalsIgnoreCase(r.getBroadcaster().getID()))) { // We cannot add the resource now. we need to first make sure there is no cached message. cache = b.getBroadcasterConfig().getBroadcasterCache(); List<Object> t = cache.retrieveFromCache(b.getID(), r.uuid()); t = b.getBroadcasterConfig().applyFilters(r, t); if (!t.isEmpty()) { logger.trace("Found Cached Messages For AtmosphereResource {} with Broadcaster {}", r.uuid(), broadcasterID); cachedMessages.addAll(t); } } else { logger.trace("Broadcaster {} is no longer available for {}", broadcasterID, r); } } return cachedMessages; }
@Override public void onRemoveAtmosphereResource(Broadcaster b, AtmosphereResource r) { // We track cancelled and resumed connection only. BroadcasterTracker t = states.get(r.uuid()); AtmosphereResourceEvent e = r.getAtmosphereResourceEvent(); if (e.isClosedByClient() || !r.isResumed() && !e.isResumedOnTimeout()) { logger.trace("Deleting the state of {} with broadcaster {}", r.uuid(), b.getID()); if (t != null) { t.remove(b); } } else { // The BroadcasterTracker was swapped onAddAtmosphereResource(b, r); logger.trace("Keeping the state of {} with broadcaster {}", r.uuid(), b.getID()); logger.trace("State for {} with broadcaster {}", r.uuid(), t != null ? t.ids() : "null"); } } }
@Override public void onAddAtmosphereResource(Broadcaster b, AtmosphereResource r) { BroadcasterTracker t = states.get(r.uuid()); if (t == null) { t = track(r); } logger.trace("Starting tracking the state of {} with broadcaster {}", r.uuid(), b.getID()); t.add(b); }