|
Hi Matthew,
I wonder if you would consider making both EventManagerInterface and SharedEventManagerInterface interfaces similar, e.g EventManagerInterface::attach($event, $callback = null, $priority = 1); and SharedEventManagerInterface::attach(array($id, $event), $callback, $priority = 1); For the shared manager interface it suggests that nothing has to be returned whereas the standard Event Manager Interface which generates the CallbackHandler is expected to be returned. Another example would be EventManagerInterface::detach($listener); and SharedEventManagerInterface::detach(CallbackHandler $listener); If the Shared Event Manager returned the CallbackHandler like the Standard Event Manager does, then the expectation and implementation would be the same? Otherwise I think I would like to see an Event Manager that can pull event listeners (or aggregates) from a service locator based on the event 'name' being the service listener alias, by default in ZF2? Regards, Greg |
|
Administrator
|
-- Greg <[hidden email]> wrote
(on Saturday, 18 August 2012, 12:31 AM -0500): > I wonder if you would consider making both EventManagerInterface and > SharedEventManagerInterface interfaces similar, e.g > > > EventManagerInterface::attach($event, $callback = null, $priority = 1); > > and > > SharedEventManagerInterface::attach(array($id, $event), $callback, > $priority = 1); No. Documenting array arguments is hard, and validating them introduces a lot of complexity. Having an explicit argument for the identifier is necessary here so that (a) it's self-documenting, (b) it's self-validating, and (c) it ensures differentiation between regular EM and SEM usage -- this latter helps you identify errors easier (missing arguments when using the SEM). > For the shared manager interface it suggests that nothing has to be > returned whereas the standard Event Manager Interface which generates > the CallbackHandler is expected to be returned. Please submit a pull request changing the return value of attach() in the SEM, then. The actual implementation _does_ return a CallbackHandler instance, which means it's simply a small documentation issue in the interface. > Another example would be > > EventManagerInterface::detach($listener); > > and > > SharedEventManagerInterface::detach(CallbackHandler $listener); > > > If the Shared Event Manager returned the CallbackHandler like the > Standard Event Manager does, then the expectation and implementation > would be the same? It's not, though. The CallbackHandler does not store the identifier, and should not, as it can be attached separately to multiple events and identifiers. As such, the signature on the SEM requires having an identifier -- and, again, this helps you with contextual debugging. > Otherwise I think I would like to see an Event Manager that can pull > event listeners (or aggregates) from a service locator based on the > event 'name' being the service listener alias, by default in ZF2? Sorry, don't quite understand what you're requesting. Can you show me some pseudo-code indicating what you'd like to do? -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc |
|
On Mon, Aug 20, 2012 at 9:33 AM, Matthew Weier O'Phinney
<[hidden email]> wrote: > Documenting array arguments is hard, and validating them introduces a > lot of complexity. Having an explicit argument for the identifier is > necessary here so that (a) it's self-documenting, (b) it's > self-validating, and (c) it ensures differentiation between regular EM > and SEM usage -- this latter helps you identify errors easier (missing > arguments when using the SEM). I agree explicit is always better. I have previously asked considering moving the identifier to the end of the method argument list. In regards to differentiation between a regular EM and an SEM, that's where I cannot change the implementation of the SEM because of its Interface. What if I do want to emulate a regular EM as an SEM? You're telling me it can't. I must be the only one it seems to just want a simple interface that would require little to no explanation. Anyhow... > > It's not, though. The CallbackHandler does not store the identifier, and > should not, as it can be attached separately to multiple events and > identifiers. As such, the signature on the SEM requires having an > identifier -- and, again, this helps you with contextual debugging. I apologize if I'm just an idiot, especially as I'm stalling from running the code, however: $listeners[] = $this->identifiers[$id]->attach($event, $callback, $priority) For each identifier a new CallbackHandler is being created and assigned to a particular identifier. Couldn't spl_object_hash of this new CallbackHandler could be used to determine which identifier it was attached to? > >> Otherwise I think I would like to see an Event Manager that can pull >> event listeners (or aggregates) from a service locator based on the >> event 'name' being the service listener alias, by default in ZF2? > > Sorry, don't quite understand what you're requesting. Can you show me > some pseudo-code indicating what you'd like to do? $em->trigger('member.create'); This in effect could replace a concrete service method entirely. All the default listeners would be pulled from the service locator config. For example public function bootstrap() { $serviceManager = $this->serviceManager; $events = $this->getEventManager(); //$events->attach($serviceManager->get('RouteListener')); //$events->attach($serviceManager->get('DispatchListener')); //$events->attach($serviceManager->get('ViewManager')); // Setup MVC Event $this->event = $event = new MvcEvent(); $event->setTarget($this); $event->setApplication($this) ->setRequest($this->getRequest()) ->setResponse($this->getResponse()) ->setRouter($serviceManager->get('Router')); // Trigger bootstrap events $events->trigger(MvcEvent::EVENT_BOOTSTRAP, $event); return $this; } E.g $em = $this->getEventManager() //whatever this means. $em->trigger('mvc.bootstrap', $event); The Event Manager will pull all the listeners for 'mvc.bootstrap' and trigger them. There would be no need to attachDefaultListeners(), and it would be easy to add, remove or manage their priority via configuration files and the EM would not need to be pre-initialized in order to do so? Basically I might like to have service object that with a concrete method that would just trigger the event: MemberService::createMember($member) { $em = $this->getEventManager(); //This is a shared event manager.. because it means less boiler plate code, e.g setEventManager + identifiers. $em->trigger('member.create', $member); } Otherwise, its seems, you're forcing us to worry about identifiers, when for the most part I don't want or need to (and others will definitely not care), and really forcing one particular type of implementation of a Shared Manager - Why couldn't a regular EM be used as an SEM and let the developer have the opportunity to handle their own implementation for integration with the ServiceManager (unless its in Zend by default)? -- Greg |
|
Administrator
|
-- Greg <[hidden email]> wrote
(on Monday, 20 August 2012, 01:39 PM -0500): > On Mon, Aug 20, 2012 at 9:33 AM, Matthew Weier O'Phinney > <[hidden email]> wrote: > > Documenting array arguments is hard, and validating them introduces a > > lot of complexity. Having an explicit argument for the identifier is > > necessary here so that (a) it's self-documenting, (b) it's > > self-validating, and (c) it ensures differentiation between regular EM > > and SEM usage -- this latter helps you identify errors easier (missing > > arguments when using the SEM). > > I agree explicit is always better. I have previously asked considering > moving the identifier to the end of the method argument list. > > In regards to differentiation between a regular EM and an SEM, that's > where I cannot change the implementation of the SEM because of its > Interface. > > What if I do want to emulate a regular EM as an SEM? You're telling me it can't. > > I must be the only one it seems to just want a simple interface that > would require little to no explanation. > > Anyhow... I disagree with the assertion that "simpler" == "better" in this case. There's a reason they are different, and it's because they do different things. The SEM does not trigger events at all, it simply collects listeners. > > It's not, though. The CallbackHandler does not store the identifier, and > > should not, as it can be attached separately to multiple events and > > identifiers. As such, the signature on the SEM requires having an > > identifier -- and, again, this helps you with contextual debugging. > > I apologize if I'm just an idiot, especially as I'm stalling from > running the code, however: > > $listeners[] = $this->identifiers[$id]->attach($event, $callback, $priority) > > For each identifier a new CallbackHandler is being created and > assigned to a particular identifier. > > Couldn't spl_object_hash of this new CallbackHandler could be used to > determine which identifier it was attached to? Using the identifier makes the operation faster, because internally, the listeners are stored in separate objects based on identifier; this means that instead of having to loop through the entire set of shared listeners, we only do a subset. (This same code is also used to find the listeners for a given identifier + event in the EM instances -- where performance is even more critical!) I'll address the service locator use case separately. -- Matthew Weier O'Phinney Project Lead | [hidden email] Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc |
|
On Mon, Aug 20, 2012 at 4:47 PM, Matthew Weier O'Phinney
<[hidden email]> wrote: > I disagree with the assertion that "simpler" == "better" in this case. I understand that, but my interpretation here is that the advanced case can and should be optional. However, this discussion could become somewhat mute if the EMs pull from the ServiceLocator instead of the SEM? Lets say a new service component needs to be created, the developer now has to learn and remember how to instantiate the identifiers for it. That's a PITA, and per my previous threads is potentially redundant since the identifiers can be determined from the target/source of the event, i.e. $this. Now I'd like to register a listener for an event of that component. So I get the SEM and now need to specify the identifier, typically some form of namespaced identifier. I then refactor the new component and its identifier changes due to a change in namespace. This means that wherever else was targeting that identifier now needs to be updated - unless we start getting messy and try to support BC. Whereas if I wanted to have the choice to just work with distinct event names, I would not have to update all those places via the SEM - unless those listeners are targeting specific sources (but these would be rare situations I'm imagining). Here by default the event names would be registered to listen to all sources for a specific event name. I think the point here, is "That is how I would like my application code to work" - I should have this choice in simple and clean fashion. I can't even try this, because of the Interface of the SEM. ZF has automatically reserved the keywords EventManager, ShareEventManager. If the EMs can work with ServceLocator, I'd suggest that it should replace the current usage of the SEM. This would allow the end user to devise their own SEM should they not wish to use the suggested ZF2 SEM - again the current SEM Interface is causing me not to be able even try to implement a different solution. I can't even reuse a single instance of an EventManager via the service locator, e.g. $serviceLocator->get('EventManager'). This is in itself is another WTF that someone else is going to have to deal with and keep reminding about. And if the SharedEventManager can't trigger events, again that is another WTF that would need reminding about. There are enough problems as it is, such as remembering to escape output etc... > I'll address the service locator use case separately. I'm looking forward to that, and wonder if somehow the identifiers could be shifted into the config too, i.e the source identifier for an event name is specified in the config (I'm not overly happy about that, but it would fit in with the current schema). -- Greg |
| Powered by Nabble | Edit this page |
