Updated Branches: refs/heads/master bbdab9af4 -> c6c6ffbdc
WICKET-4957: added listener for new suspended connections Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c6c6ffbd Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c6c6ffbd Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c6c6ffbd Branch: refs/heads/master Commit: c6c6ffbdc79a25e46c0cba0078c2e22c7fe3a054 Parents: 91885d9 Author: Emond Papegaaij <[email protected]> Authored: Thu Jan 10 10:09:41 2013 +0100 Committer: Emond Papegaaij <[email protected]> Committed: Thu Jan 10 10:09:41 2013 +0100 ---------------------------------------------------------------------- .../org/apache/wicket/atmosphere/EventBus.java | 84 +++++++++++++-- .../atmosphere/ResourceRegistrationListener.java | 51 +++++++++ 2 files changed, 126 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/c6c6ffbd/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/EventBus.java ---------------------------------------------------------------------- diff --git a/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/EventBus.java b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/EventBus.java index 4901c7a..e9a3cd0 100644 --- a/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/EventBus.java +++ b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/EventBus.java @@ -19,7 +19,10 @@ package org.apache.wicket.atmosphere; import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.CopyOnWriteArrayList; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; @@ -42,7 +45,6 @@ import org.slf4j.LoggerFactory; import com.google.common.collect.Collections2; import com.google.common.collect.HashMultimap; -import com.google.common.collect.Iterators; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -95,6 +97,8 @@ public class EventBus implements UnboundListener private Map<String, PageKey> trackedPages = Maps.newHashMap(); + private List<ResourceRegistrationListener> registrationListeners = new CopyOnWriteArrayList<ResourceRegistrationListener>(); + /** * Creates and registers an {@code EventBus} for the given application. The first broadcaster * returned by the {@code BroadcasterFactory} is used. @@ -124,6 +128,14 @@ public class EventBus implements UnboundListener } /** + * @return The {@link Broadcaster} used by the {@code EventBus} to broadcast messages to. + */ + public Broadcaster getBroadcaster() + { + return broadcaster; + } + + /** * Registers a page for the given tracking-id in the {@code EventBus}. * * @param trackingId @@ -134,8 +146,12 @@ public class EventBus implements UnboundListener PageKey oldPage = trackedPages.remove(trackingId); PageKey pageKey = new PageKey(page.getPageId(), Session.get().getId()); if (oldPage != null && !oldPage.equals(pageKey)) + { subscriptions.removeAll(oldPage); + fireUnregistration(trackingId); + } trackedPages.put(trackingId, pageKey); + fireRegistration(trackingId, page); log.info("registered page {} for session {}", new Object[] { pageKey.getPageId(), pageKey.getSessionId() }); } @@ -175,10 +191,14 @@ public class EventBus implements UnboundListener public synchronized void unregisterConnection(String trackingId) { PageKey pageKey = trackedPages.remove(trackingId); - if (log.isInfoEnabled() && pageKey != null) + if (pageKey != null) { - log.info("unregistering page {} for session {}", new Object[] { pageKey.getPageId(), - pageKey.getSessionId() }); + fireUnregistration(trackingId); + if (log.isInfoEnabled()) + { + log.info("unregistering page {} for session {}", new Object[] { + pageKey.getPageId(), pageKey.getSessionId() }); + } } } @@ -290,10 +310,56 @@ public class EventBus implements UnboundListener public synchronized void sessionUnbound(String sessionId) { log.info("Session unbound {}", sessionId); - Iterator<PageKey> it = Iterators.concat(trackedPages.values().iterator(), - subscriptions.keySet().iterator()); - while (it.hasNext()) - if (it.next().isForSession(sessionId)) - it.remove(); + Iterator<Entry<String, PageKey>> pageIt = trackedPages.entrySet().iterator(); + while (pageIt.hasNext()) + { + Entry<String, PageKey> curEntry = pageIt.next(); + if (curEntry.getValue().isForSession(sessionId)) + { + pageIt.remove(); + fireUnregistration(curEntry.getKey()); + } + } + Iterator<PageKey> subscriptionIt = subscriptions.keySet().iterator(); + while (subscriptionIt.hasNext()) + if (subscriptionIt.next().isForSession(sessionId)) + subscriptionIt.remove(); + } + + /** + * Add a new {@link ResourceRegistrationListener} to the {@code EventBus}. This listener will be + * notified on all Atmosphere resource registrations and unregistrations. + * + * @param listener + */ + public void addRegistrationListener(ResourceRegistrationListener listener) + { + registrationListeners.add(listener); + } + + /** + * Removes a previously added {@link ResourceRegistrationListener}. + * + * @param listener + */ + public void removeRegistrationListener(ResourceRegistrationListener listener) + { + registrationListeners.add(listener); + } + + private void fireRegistration(String uuid, Page page) + { + for (ResourceRegistrationListener curListener : registrationListeners) + { + curListener.resourceRegistered(uuid, page); + } + } + + private void fireUnregistration(String uuid) + { + for (ResourceRegistrationListener curListener : registrationListeners) + { + curListener.resourceUnregistered(uuid); + } } } http://git-wip-us.apache.org/repos/asf/wicket/blob/c6c6ffbd/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/ResourceRegistrationListener.java ---------------------------------------------------------------------- diff --git a/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/ResourceRegistrationListener.java b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/ResourceRegistrationListener.java new file mode 100644 index 0000000..cdeb439 --- /dev/null +++ b/wicket-experimental/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/ResourceRegistrationListener.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.atmosphere; + +import org.apache.wicket.Page; +import org.apache.wicket.Session; +import org.apache.wicket.request.cycle.RequestCycle; + +/** + * Listener interface for intercepting the registration of Atmosphere resources for pages. For every + * page that has an Atmosphere resource, {@link #resourceRegistered(String, Page)} will be called. + * When the suspended connection is terminated (by a page unload, session termination or a closed + * connection), {@link #resourceUnregistered(String)} is invoked. + * + * @author papegaaij + */ +public interface ResourceRegistrationListener +{ + /** + * Invoked when a new suspended connection is setup and registered for a page. This method is + * invoked in the context of a wicket request where the {@link RequestCycle} and {@link Session} + * are available. The {@code Page} is attached and it is safe to call methods on it. However, + * you should never keep a reference to the page. Not only will this create memory leaks, but + * can only be accessed from the context of a Wicket request on that page. + * + * @param uuid + * @param page + */ + public void resourceRegistered(String uuid, Page page); + + /** + * Invoked when a suspended connection is terminated and unregistered. + * + * @param uuid + */ + public void resourceUnregistered(String uuid); +}
