[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/LocalEventService - LocalEventService.py:1.1.2.5 LocalSubscriptionAware.py:1.1.2.2
Gary Poster
garyposter@earthlink.net
Sun, 19 May 2002 13:43:31 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/LocalEventService
In directory cvs.zope.org:/tmp/cvs-serv8180/lib/python/Zope/App/OFS/Services/LocalEventService
Modified Files:
Tag: Zope-3x-branch
LocalEventService.py LocalSubscriptionAware.py
Log Message:
more tests and fixes to the local event service
=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventService.py 1.1.2.4 => 1.1.2.5 ===
from Zope.Event.ISubscriber import ISubscriber
from LocalServiceSubscribable import LocalServiceSubscribable
-from Zope.ComponentArchitecture import getNextService, getAdapter
+from Zope.ComponentArchitecture import getNextService, getAdapter, getService
from Zope.App.OFS.ServiceManager.IBindingAware import IBindingAware
from Zope.ContextWrapper import ContextMethod
from Zope.Proxy.ProxyIntrospection import removeAllProxies
@@ -31,6 +31,7 @@
from LocalSubscriptionAware import LocalSubscriptionAware
from Interface.Attribute import Attribute
from Zope.Event.GlobalEventService import eventService
+from Zope.Event.IEvent import IEvent
class ILocalEventService(IEventService, ISubscriber, IBindingAware, ISubscriptionAware):
@@ -121,16 +122,45 @@
clean_self=removeAllProxies(wrapped_self)
subscriber=PathSubscriber(wrapped_self)
clean_self._v_unbinding=1
- for subscribable_path in clean_self._subscriptions:
- subscribable=getAdapter(wrapped_self, ITraverser).traverse(subscribable_path)
+ for subscription in clean_self._subscriptions:
+ subscribable=getAdapter(wrapped_self, ITraverser).traverse(subscription[0])
subscribable.unsubscribe(subscriber)
clean_self._subscriptions=()
for subscriber in clean_self._subscribers:
- wrapped_self.unsubscribe(subscriber)
+ clean_self.__unsubscribeAllFromSelf(wrapped_self, subscriber[0])
clean_self._v_unbinding=None
unbound=ContextMethod(unbound)
+ def __unsubscribeAllFromSelf(clean_self, wrapped_self, subscriber):
+ """this is *not* an interface function, and should not be used
+ outside of this class"""
+
+ wrapped_subscriber=ContextWrapper(subscriber, wrapped_self)
+
+ for subscriber_index in range(len(clean_self._subscribers)):
+ sub=clean_self._subscribers[subscriber_index]
+ if sub[0]==subscriber:
+ ev_set=sub[1]
+ break
+ else:
+ raise NotFoundError(subscriber)
+ do_alert=ISubscriptionAware.isImplementedBy(subscriber)
+ for ev_type in ev_set:
+ subscriptions = clean_self._registry.getJustForType(ev_type)
+ subs=subscriptions[:]
+ subscriptions[:] = []
+ for sub in subs:
+ if sub[0] == subscriber: # deleted (not added back)
+ if do_alert:
+ wrapped_subscriber.unsubscribedFrom(
+ wrapped_self, ev_type or IEvent, sub[1])
+ # IEvent switch is to make optimization transparent
+ else: # kept (added back)
+ subscriptions.append(sub)
+ del clean_self._subscribers[subscriber_index]
+ clean_self._registry=clean_self._registry #trigger persistence, if pertinent
+
def unsubscribedFrom(wrapped_self, subscribable, event_type, filter):
"see ISubscriptionAware"
clean_self=removeAllProxies(wrapped_self)
@@ -144,8 +174,11 @@
clean_subscribable=removeAllProxies(subscribable)
if IEventService.isImplementedBy(removeAllProxies(clean_subscribable)):
context=getService(wrapped_self, "Events")
- while removeAllProxies(context) is clean_subscribable:
- context=getService(context, "Events")
+ # we do this instead of getNextService because the order
+ # of unbinding and notification of unbinding is not
+ # guaranteed
+ while removeAllProxies(context) in (clean_subscribable, clean_self):
+ context=getNextService(context, "Events")
# XXX as usual, we *must not* be working with a global service;
# this probably should raise an error if service is global service...
# that leaves replacing top level event services an
=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalSubscriptionAware.py 1.1.2.1 => 1.1.2.2 ===
def subscribedTo(self, subscribable, event_type, filter):
- subscribable_path=getAdapter(
- subscribable, ITraverser).getPhysicalPath()
+ #subscribable_path=getAdapter(
+ # subscribable, ITraverser).getPhysicalPath()
+ subscribable_path="/%s" % "/".join(getAdapter(
+ subscribable, ITraverser).getPhysicalPath())
+ # XXX right now the conversion to a string is necessary because
+ # the tuple path returned by the Traverser does not include an
+ # empty initial space to represent the root
if (subscribable_path, event_type, filter) not in self._subscriptions:
self._subscriptions+=((subscribable_path,event_type, filter),)
def unsubscribedFrom(self, subscribable, event_type, filter):
- subscribable_path=getAdapter(
- subscribable, ITraverser).getPhysicalPath()
+ subscribable_path="/%s" % "/".join(getAdapter(
+ subscribable, ITraverser).getPhysicalPath())
sub=list(self._subscriptions)
sub.remove((subscribable_path, event_type, filter))
- self._subscriptions=sub
+ self._subscriptions=tuple(sub)