[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services/LocalEventService - LocalEventChannel.py:1.7 LocalEventService.py:1.11 ProtoServiceEventChannel.py:1.4 LocalServiceSubscribable.py:1.9 LocalSubscribable.py:1.7

Ulrich Eck ueck@net-labs.de
Thu, 12 Dec 2002 15:05:52 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Services/LocalEventService
In directory cvs.zope.org:/tmp/cvs-serv30235

Modified Files:
	LocalEventChannel.py LocalEventService.py 
	ProtoServiceEventChannel.py LocalServiceSubscribable.py 
	LocalSubscribable.py 
Log Message:
Refactored LocalEventService to store and use locations instead of
references to subscribers.

now every subscriber is notified within correct context to be able
to use local services and the like.

changes are incompatible to existing subscriptions !!! you need
to delete all subscriptions (or subscribables) from your db
or reinitialize ...



=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventChannel.py 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventChannel.py:1.6	Mon Nov 11 03:38:36 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventChannel.py	Thu Dec 12 15:05:51 2002
@@ -21,7 +21,7 @@
 from Zope.Event.IEventChannel import IEventChannel
 from Zope.ContextWrapper import ContextMethod
 from Zope.Proxy.ProxyIntrospection import removeAllProxies
-from Zope.Proxy.ContextWrapper import ContextWrapper
+from Zope.App.Traversing import traverse
 
 class LocalEventChannel(LocalSubscribable):
     
@@ -38,8 +38,10 @@
         # subscriptionses = clean_self._registry.getAllForObject(event)
 
         for subscriptions in subscriptionses:
-            for subscriber,filter in subscriptions:
+            # for subscriber_path, filter in subscriptions:
+            for subscriber_path, filter in subscriptions:
                 if filter is not None and not filter(event):
                     continue
-                ContextWrapper(subscriber, wrapped_self).notify(event)
+                # XXX resolve subscriber_path
+                traverse(wrapped_self, subscriber_path).notify(event)
     notify = ContextMethod(notify)


=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventService.py 1.10 => 1.11 ===
--- Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventService.py:1.10	Sun Dec  1 05:32:29 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalEventService.py	Thu Dec 12 15:05:51 2002
@@ -22,6 +22,7 @@
 from Zope.Event.IEventService import IEventService
 from Zope.Event.ISubscriptionAware import ISubscriptionAware
 from Zope.App.Traversing.ITraverser import ITraverser
+from Zope.App.Traversing import traverse
 from Zope.ComponentArchitecture import getAdapter, getService
 from Zope.App.ComponentArchitecture.NextService import getNextService
 from Zope.ContextWrapper import ContextMethod
@@ -29,7 +30,8 @@
 from Zope.Proxy.ContextWrapper import ContextWrapper
 from Zope.Proxy.ProxyIntrospection import removeAllProxies
 
-from PathSubscriber import PathSubscriber
+
+
 from ProtoServiceEventChannel import ProtoServiceEventChannel
 
 class LocalEventService(ProtoServiceEventChannel):
@@ -58,10 +60,12 @@
         subscriptionses = clean_self._registry.getAllForObject(event)
 
         for subscriptions in subscriptionses:
-            for subscriber,filter in subscriptions:
+            # for subscriber_path, filter in subscriptions:
+            for subscriber_path,filter in subscriptions:
                 if filter is not None and not filter(event):
                     continue
-                ContextWrapper(subscriber, wrapped_self).notify(event)
+                # XXX resolve subscriber_path
+                traverse(wrapped_self, subscriber_path).notify(event)
 
         publishedEvents = getattr(clean_self, "_v_publishedEvents", None)
         if publishedEvents is None:
@@ -81,10 +85,12 @@
             subscriptionses = clean_self._registry.getAllForObject(event)
 
             for subscriptions in subscriptionses:
-                for subscriber,filter in subscriptions:
+                # for subscriber_path, filter in subscriptions:
+                for subscriber_path, filter in subscriptions:
                     if filter is not None and not filter(event):
                         continue
-                    ContextWrapper(subscriber, wrapped_self).notify(event)
+                    # XXX resolve subscriber_path
+                    traverse(wrapped_self, subscriber_path).notify(event)
     notify = ContextMethod(notify)
     
     def bound(wrapped_self, name):
@@ -98,7 +104,8 @@
                 # global event service we're going to have to
                 # set something special up--something that subscribes
                 # every startup...
-                es.subscribe(PathSubscriber(wrapped_self))
+                # XXX just pass wrapped_self
+                es.subscribe(wrapped_self)
     bound = ContextMethod(bound)
     
     # _unbound = ProtoServiceEventChannel.unbound # see comment below
@@ -120,29 +127,34 @@
         #
         # so we're doing a copy and paste from ProtoServiceEventChannel:
         # start copy/paste
-        subscriber = PathSubscriber(wrapped_self)
+        # XXX subscriber = wrapped_self
         for subscription in clean_self._subscriptions:
             subscribable = getAdapter(
                 wrapped_self, ITraverser).traverse(subscription[0])
-            subscribable.unsubscribe(subscriber)
+            subscribable.unsubscribe(wrapped_self)
         clean_self._subscriptions = ()
         clean_self._serviceName = None
         # end copy/paste
         
+        # ambigous name subscriber -> (subscriber_path, filter, )
         for subscriber in clean_self._subscribers:
             clean_self.__unsubscribeAllFromSelf(wrapped_self, subscriber[0])
         # unset flag
         clean_self._v_unbinding = None
     unbound = ContextMethod(unbound)
     
-    def __unsubscribeAllFromSelf(clean_self, wrapped_self, subscriber):
+    # XXX gets subscriber_path as last argument
+    def __unsubscribeAllFromSelf(clean_self, wrapped_self, subscriber_path):
         """this is *not* an interface function, and should not be used
         outside of this class"""
-        wrapped_subscriber = ContextWrapper(subscriber, wrapped_self)
+        
+        # XXX resolve subscriber from path first
+        subscriber = traverse(wrapped_self, subscriber_path)
         
         for subscriber_index in range(len(clean_self._subscribers)):
             sub = clean_self._subscribers[subscriber_index]
-            if sub[0] == subscriber:
+            # XXX subscriber_path
+            if sub[0] == subscriber_path:
                 ev_set = sub[1]
                 break
         else:
@@ -154,9 +166,10 @@
             subs=subscriptions[:]
             subscriptions[:] = []
             for sub in subs:
-                if sub[0] == subscriber: # deleted (not added back)
+                # XXX subscriber_path
+                if sub[0] == subscriber_path: # deleted (not added back)
                     if do_alert:
-                        wrapped_subscriber.unsubscribedFrom(
+                        subscriber.unsubscribedFrom(
                             wrapped_self, ev_type or IEvent, sub[1])
                         # IEvent switch is to make optimization transparent
                 else: # kept (added back)
@@ -189,6 +202,8 @@
                 # service...
                 # that leaves replacing top level event services an
                 # interesting question, however
-                context.subscribe(PathSubscriber(wrapped_self))
+                
+                # XXX just pass wrapped_self
+                context.subscribe(wrapped_self)
     unsubscribedFrom = ContextMethod(unsubscribedFrom)
 


=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/ProtoServiceEventChannel.py 1.3 => 1.4 ===
--- Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/ProtoServiceEventChannel.py:1.3	Mon Nov 11 03:38:36 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/ProtoServiceEventChannel.py	Thu Dec 12 15:05:51 2002
@@ -21,7 +21,6 @@
 from Zope.App.Traversing.ITraverser import ITraverser
 from Zope.Proxy.ProxyIntrospection import removeAllProxies
 from Zope.ComponentArchitecture import getAdapter, getService
-from PathSubscriber import PathSubscriber
 from LocalSubscriptionAware import LocalSubscriptionAware
 from Zope.ContextWrapper import ContextMethod
 from LocalEventChannel import LocalEventChannel
@@ -75,7 +74,7 @@
                 # set something special up -- something that subscribes
                 # every startup...
                 es.subscribe(
-                    PathSubscriber(wrapped_self),
+                    wrapped_self,
                     clean_self._subscribeToServiceInterface,
                     clean_self._subscribeToServiceFilter
                     )
@@ -85,11 +84,10 @@
     def unbound(wrapped_self, name):
         "see IBindingAware"
         clean_self = removeAllProxies(wrapped_self)
-        subscriber = PathSubscriber(wrapped_self)
         for subscription in clean_self._subscriptions:
             subscribable = getAdapter(
                 wrapped_self, ITraverser).traverse(subscription[0])
-            subscribable.unsubscribe(subscriber)
+            subscribable.unsubscribe(wrapped_self)
         clean_self._subscriptions = ()
         clean_self._serviceName = None
 


=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalServiceSubscribable.py 1.8 => 1.9 ===
--- Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalServiceSubscribable.py:1.8	Fri Dec  6 13:03:31 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalServiceSubscribable.py	Thu Dec 12 15:05:51 2002
@@ -24,6 +24,7 @@
 from Zope.Proxy.ContextWrapper import ContextWrapper
 from LocalSubscribable import LocalSubscribable
 from Zope.App.ComponentArchitecture.NextService import getNextService, queryNextService
+from Zope.App.Traversing import getPhysicalPathString
 
 class LocalServiceSubscribable(LocalSubscribable):
     """a local mix-in for services"""
@@ -40,15 +41,15 @@
                     subscriber,
                     event_type=None,
                     filter=None):
-        # might be wrapped, might not
-        subscriber = removeAllProxies(subscriber) 
+        # subscriber must be wrapped
+        subscriber_path = getPhysicalPathString(subscriber)
         
         clean_self = removeAllProxies(wrapped_self)
-        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:
+            # XXX subscriber_path
+            if sub[0] == subscriber_path:
                 ev_set = sub[1]
                 break
         else:
@@ -76,15 +77,17 @@
             else:
                 subscriptions = clean_self._registry.get(ev_type)
                 try:
-                    subscriptions.remove((subscriber, filter))
+                    # XXX subscriber_path
+                    subscriptions.remove((subscriber_path, filter))
                 except ValueError:
                     raise NotFoundError(subscriber, event_type, filter)
                 if do_alert:
-                    wrapped_subscriber.unsubscribedFrom(
+                    subscriber.unsubscribedFrom(
                         wrapped_self, event_type, filter)
                 if len(ev_set) == 1:
                     for sub in subscriptions:
-                        if sub[0] == subscriber:
+                        # XXX subscriber_path
+                        if sub[0] == subscriber_path:
                             break
                     else:
                         del clean_self._subscribers[subscriber_index]
@@ -95,9 +98,10 @@
                 subs = subscriptions[:]
                 subscriptions[:] = []
                 for sub in subs:
-                    if sub[0] == subscriber: # deleted (not added back)
+                    # XXX subscriber_path
+                    if sub[0] == subscriber_path: # deleted (not added back)
                         if do_alert:
-                            wrapped_subscriber.unsubscribedFrom(
+                            subscriber.unsubscribedFrom(
                                 wrapped_self, ev_type or IEvent, sub[1])
                             # IEvent switch is to make optimization
                             # transparent (see *** comment above in
@@ -112,9 +116,8 @@
     unsubscribe = ContextMethod(unsubscribe)
     
     def listSubscriptions(wrapped_self, subscriber, event_type=None):
-        # might be wrapped, might not
-        subscriber = removeAllProxies(subscriber)
-        
+        # subscriber must be wrapped
+       
         clean_self = removeAllProxies(wrapped_self)
         result = LocalSubscribable.listSubscriptions(
             clean_self, subscriber, event_type)


=== Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalSubscribable.py 1.6 => 1.7 ===
--- Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalSubscribable.py:1.6	Wed Nov 27 21:45:47 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/LocalEventService/LocalSubscribable.py	Thu Dec 12 15:05:51 2002
@@ -25,6 +25,8 @@
 from Zope.Proxy.ContextWrapper import ContextWrapper
 from Zope.Event.Subscribable import Subscribable
 from Persistence import Persistent
+from Zope.App.Traversing import traverse, getPhysicalPathString
+from Zope.App.Traversing import locationAsUnicode
 
 class LocalSubscribable(Persistent, Subscribable):
     """a local mix-in"""
@@ -39,14 +41,14 @@
                   subscriber,
                   event_type=IEvent,
                   filter=None):
-        # might be wrapped, might not
-        subscriber = removeAllProxies(subscriber)
         
+        # subscriber needs to be wrapped
+        subscriber_path = getPhysicalPathString(subscriber)
+       
         clean_self = removeAllProxies(wrapped_self)
-        wrapped_subscriber = ContextWrapper(subscriber, wrapped_self)
         
         if ISubscriptionAware.isImplementedBy(subscriber):
-            wrapped_subscriber.subscribedTo(
+            subscriber.subscribedTo(
                 wrapped_self,
                 event_type,
                 filter)
@@ -58,15 +60,18 @@
         if subscribers is None:
             subscribers = []
             clean_self._registry.register(ev_type, subscribers)
-        subscribers.append((subscriber, filter))
+        # XXX subscriber_path
+        subscribers.append((subscriber_path, filter))
 
         subs = clean_self._subscribers
         for sub in subs:
-            if sub[0] == subscriber:
+            # XXX subscriber_path
+            if sub[0] == subscriber_path:
                 sub[1][ev_type] = 1
                 break
         else:
-            subs.append((subscriber,{ev_type:1}))
+            # XXX subscriber_path
+            subs.append((subscriber_path,{ev_type:1}))
         
         clean_self._p_changed = 1 #trigger persistence
         # XXX should this and similar be done earlier in the method?
@@ -79,15 +84,15 @@
                     subscriber,
                     event_type = None,
                     filter = None):
-        # subscriber might be wrapped, might not
-        subscriber = removeAllProxies(subscriber) 
+        # subscriber must be wrapped
+        subscriber_path = getPhysicalPathString(subscriber)
         
         clean_self = removeAllProxies(wrapped_self)
-        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:
+            # XXX subscriber_path
+            if sub[0] == subscriber_path:
                 ev_set = sub[1]
                 break
         else:
@@ -106,15 +111,17 @@
             if not subscriptions:
                 raise NotFoundError(subscriber, event_type, filter)
             try:
-                subscriptions.remove((subscriber, filter))
+                # XXX subscriber_path
+                subscriptions.remove((subscriber_path, filter))
             except ValueError:
                 raise NotFoundError(subscriber, event_type, filter)
             if do_alert:
-                wrapped_subscriber.unsubscribedFrom(
+                subscriber.unsubscribedFrom(
                     wrapped_self, event_type, filter)
             if len(ev_set) == 1:
                 for sub in subscriptions:
-                    if sub[0] == subscriber:
+                    # XXX subscriber_path
+                    if sub[0] == subscriber_path:
                         break
                 else:
                     del clean_self._subscribers[subscriber_index]
@@ -124,9 +131,10 @@
                 subs=subscriptions[:]
                 subscriptions[:] = []
                 for sub in subs:
-                    if sub[0] == subscriber: # deleted (not added back)
+                    # XXX subscriber_path
+                    if sub[0] == subscriber_path: # deleted (not added back)
                         if do_alert:
-                            wrapped_subscriber.unsubscribedFrom(
+                            subscriber.unsubscribedFrom(
                                 wrapped_self, ev_type or IEvent, sub[1])
                             # IEvent switch is to make optimization
                             # transparent
@@ -137,3 +145,36 @@
         # XXX should be done earlier?  Ask Shane
     
     unsubscribe = ContextMethod(unsubscribe)
+
+    def listSubscriptions(self, subscriber, event_type=None):
+        # subscriber must be wrapped
+        subscriber_path = getPhysicalPathString(subscriber)
+        
+        result=[]
+        if event_type:
+            ev_type=event_type
+            if event_type is IEvent:
+                ev_type=None # handle optimization
+            subscriptions = self._registry.get(ev_type)
+            if subscriptions:
+                for sub in subscriptions:
+                    # XXX subscriber_path
+                    if sub[0]==subscriber_path:
+                        result.append((event_type, sub[1]))
+        else:
+            for subscriber_index in range(len(self._subscribers)):
+                sub=self._subscribers[subscriber_index]
+                # XXX subscriber_path
+                if sub[0]==subscriber_path:
+                    ev_set=sub[1]
+                    break
+            else:
+                return result
+            for ev_type in ev_set:
+                subscriptions = self._registry.get(ev_type)
+                if subscriptions:
+                    for sub in subscriptions:
+                        # XXX subscriber_path
+                        if sub[0]==subscriber_path:
+                            result.append((ev_type or IEvent, sub[1]))
+        return result