ACK!!!!! Re: [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

Gary Poster gary@modernsongs.com
Thu, 12 Dec 2002 15:13:49 -0500


ACK!!!!!

I'm assuming this has been discussed quite a bit at the sprint, but I am 
  *very* concerned about this approach.

it makes it impossible to use other kinds of indirect subscribers, such 
as object hub subscribers, an implementation of which I have in my 
sandbox.  Descriptions are also in the Zope.Event directory.

OK, yes, sprint people are in charge of the sprint, but SteveA or 
someone, can you at least shoot a mail that this change was thought 
through and blessed and will be explained later?

Gary



Ulrich Eck wrote:
> 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
> 
> 
> _______________________________________________
> Zope3-Checkins mailing list
> Zope3-Checkins@zope.org
> http://lists.zope.org/mailman/listinfo/zope3-checkins
> 
>