If I have multipile models and I working heavy with events so in my AppServiceProvider I create a observer for my models like:
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
User::observe(UserObserver::class);
User2::observe(UserObserver2::class);
User3::observe(UserObserver3::class);
User4::observe(UserObserver4::class);
User5::observe(UserObserver5::class);
User6::observe(UserObserver6::class);
User7::observe(UserObserver7::class);
User8::observe(UserObserver8::class);
User9::observe(UserObserver9::class);
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}
does it create some performance penalty? as If I understand the observe method correctly for every app access it will loop through all my models observers method and will match them to eloquent events so if I have 30 models observers it can cause a bad performance?
is there some clever way of declaring the observe class only when the model is in use? so instead of declaring the observers in each app access even when not needed each model will know about its observer only when its in use?
With model observers specifically, there is a performance impact that's greater than typical event registration. The extra overhead comes from how Laravel handles the observer event mapping. Since the events being registered are based on the existing methods, Laravel makes a minimum of 13 calls to method_exists per observer.
For just a couple of observers, that isn't a big deal. However, if you start using observers for audit trail processes and involve several models, this cost can start to add up.
As an example, I once worked on application that had four generalized observers that observed around 300 models between them (some of the models were shared by observers). This turned into over 600 Model::observe calls, and therefore over 7,800 calls into method_exists.
I've actually created a package (reedware/laravel-events) to solve this problem. You instead register observers (and other events) through a configuration file, and the events can be cached. The caching mechanism actually works for observers too (which doesn't work for Laravel out of the box), so the cost of observers becomes extremely minimal.
Alternatively, you could ditch the observer design pattern, and use the Model::creating(...) hooks within a bootable trait, or just throw custom events and register listeners for them.
If you use events with Laravel, the events will be registered (but not fired) on every request.
To be more precise, that the events will be registered means that User::observe(UserObserver::class); will loop through all methods of UserObserver and save them in an array of a dispatcher of the User class. Only if an update / create method through the User model is executed, the registered UserObserver method will be fired, i.e. called from the dispatcher.
So if you have 30 Models each with 5 methods in the Observer class, that would be 150 array bindings on every request to the dispatcher. However, the methods of your observer are not called during each request, only when the event fires. Thus, I don't believe that 150 array assignments will make an impact on the request time, compared to the time it takes to load a 120kb Logo or to execute query calls.
Best thing is of course to measure it for yourself. Measure the time of a request with binding the observer and without. You could use debugbar for it.
Side note: Using deferred providers won't make any difference, because you have to place the observer calls into the boot method of a provider. From the docs:
If your provider is only registering bindings in the service container, you may choose to defer its registration until one of the registered bindings is actually needed.
Related
I have a projection class (to build a read model) and I want to add an interceptor for its events in a way that if the id passed in the event leads to a null object (non-existent in my db) then I want to block it, otherwise let it pass.
This way I will escape adding a null checker on EVERY event handler.
#EventHandler
public void onEvent(Event event) {
Entity entity = getEntity(event.getId());
if(entity!=null){ // what I don't want to add on every event handler
dostuff();
}
}
I found that axon provides an interface called EventListener but I'm not sure how to work with it and I'm not sure if this will be intercepting ALL of my events or if I will be able to intercept select events.
There is no mention anywhere for this interface but in the official documentation (with no actual examples or so)
You are right on the part the the Reference Guide still needs some improvements #bleh10 - I can assure you, they're being worked on, the team is just spread out relatively thin.
In absence of the sought after example, I think I can give you some guidance.
What you're looking for is a MessageHandlerInterceptor implementation, specifically for the EventMessage type. As the naming suggests, it intercepts messages prior to being handled, which corresponds perfectly with the question you've posed.
Secondly, you obviously need a place to configure these. Within an Axon application, the technical aspect of delivering events to your #EventHandler annotated methods, is the Event Processor. As such, it is in charge of ensuring the Event Messages flowing through it are intercepted as desired.
Hence, the place to configure your EventMessage MessageHandlerInterceptor, is on the EventProcessor implementation you've chosen. To ensure a given Event Handling Component is set in a specific EventProcessor, you can specify it's Processing Group by annotating the class with the #ProcessingGroup annotation.
From there on, you can easily configure specific properties for your Event Processor by utilizing the EventProcessingConfigurer. More specifically, I'd suggest to use the EventProcessingConfigurer#registerHandlerInterceptor(String, Function<Configuration, MessageHandlerInterceptor<? super EventMessage<?>>>) method for this.
The first String parameter is meant to describe the name of your Processing Group. The second is a Function which receive the Axon Configuration and should output a MessageHandlerInterceptor which can deal with the EventMessage class.
Hope this helps you out!
I have an axon aggregate. It handle command and before applying event has to invoke third party service for validation some parameters, according to this validation i apply events or not. Is it good practice? Or I have make validation before i send command?
#Aggregate
public class SomeAggregate {
[...]
#CommandHandler
public void someHandler() {
if(thirdPartyService.invoke) {
apply(...)
}
}
}
If it's a non-blocking (domain) service, something like a finite state machine, it's okay to call from within the aggregate, since it's most likely going to finish soon.
However, 'third party service' to me sounds like an outbound call, which might take some time.
When Axon loads an aggregate, it blocks the aggregate so no other thread can change it's state/handle commands on it.
A third-party service would mean that the aggregate is blocked even longer.
Hence, I would suggest not calling a third party service in your aggregate.
Either call the service prior to entering the aggregate or perform a compensating action after command handling was finalized to revert the decision. Which of the two makes most sense in your scenario, is dependent on your domain. I see "pre-validation" through the third-party service however as the most reasonable option to take.
It depends. If your third party service has side effects and isn't idempotent then I'm not sure what to do (I'm still trying to figure it out).
If it does have side effects, then I would want the aggregate to block / lock and use the aggregate's state / history to carefully manage such an interaction like this
#Aggregate
public class SomeAggregate {
[...]
#CommandHandler
public void someHandler() {
/*
Reason about whether its appropriate to send a request.
e.g. if a request has been sent but no response has been received,
then depending on the third party service it might be in an indeterminate state.
Instead of trying to interact with it, it might be better
to notify someone instead.
*/
rejectIfNotSafe()
/*
Effectively locks this interaction / any other instances in the same path
should get a concurrent modification exception when trying to commit this event.
*/
commit(new ThirdPartyServiceRequested())
if(thirdPartyService.invoke) {
apply(...)
}
}
}
But Axon's 'unit of work' means that the emitted events won't be published / committed until the command handler has completed, so we can't guard is this manner.
Any ideas?
Are model events the same as regular events. And do you place model events as regular events? I'm trying to create a profile row when a user registers.
You can handle model events via some helper functions or using model observers.
But yes, behind the scenes, these events are fired Laravel's event dispatcher, so technically you could bind functions to those events via the Event facade, too.
I'm working in the Symfony2 framework and wondering when would one use a Doctrine subscriber versus a listener. Doctrine's documentation for listeners is very clear, however subscribers are rather glossed over. Symfony's cookbook entry is similar.
From my point of view, there is only one major difference:
The Listener is signed up specifying the events on which it listens.
The Subscriber has a method telling the dispatcher what events it is listening to
This might not seem like a big difference, but if you think about it, there are some cases when you want to use one over the other:
You can assign one listener to many dispatchers with different events, as they are set at registration time. You only need to make sure every method is in place in the listener
You can change the events a subscriber is registered for at runtime and even after registering the subscriber by changing the return value of getSubscribedEvents (Think about a time where you listen to a very noisy event and you only want to execute something one time)
There might be other differences I'm not aware of though!
Don't know whether it is done accidentally or intentionally.. But subscribers have higher priority that listeners - https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php#L73-L98
From doctrine side, it doesn't care what it is (listener or subscriber), eventually both are registered as listeners - https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/EventManager.php#L137-L140
This is what I spotted.
You should use event subscriber when you want to deal with multiple events in one class, for example in this symfony2 doc page article, one may notice that event listener can only manage one event, but lets say you want to deal with several events for one entity, prePersist, preUpdate, postPersist etc... if you use event listener you would have to code several event listener, one for each event, but if you go with event subscriber you just have to code one class the event susbcriber, look that with the event subscriber you can manage more than one event in one class, well thats the way i use it, i preffer to code focused in what the model business need, one example of this may be went you want to handle several lifecycle events globaly only for a group of your entities, to do that you can code a parent class and defined those global methods in it, then make your entities inherit that class and later in your event susbcriber you subscribe every event you want, prePersist, preUpdate, postPersist etc... and then ask for that parent class and execute those global methods.
Another important thing: Doctrine EventSubscribers do not allow you to set a priority.
Read more on this issue here
Both allow you to execute something on a particular event pre / post persist etc.
However listeners only allow you to execute behaviours encapsulated within your Entity. So an example might be updating a "date_edited" timestamp.
If you need to move outside the context of your Entity, then you'll need a subscriber. A good example might be for calling an external API, or if you need to use / inspect data not directly related to your Entity.
Here is what the doc is saying about that in 4.1.
As this is globally applied to events, I suppose it's also valid for Doctrine (not 100% sure).
Listeners or Subscribers
Listeners and subscribers can be used in the same application indistinctly. The decision to use either of them is usually a matter
of personal taste. However, there are some minor advantages for each
of them:
Subscribers are easier to reuse because the knowledge of the events is kept in the class rather than in the service definition.
This is
the reason why Symfony uses subscribers internally;
Listeners are more flexible because bundles can enable or disable each of them conditionally depending on some configuration value.
http://symfony.com/doc/master/event_dispatcher.html#listeners-or-subscribers
From the documentation :
The most common way to listen to an event is to register an event
listener with the dispatcher. This listener can listen to one or more
events and is notified each time those events are dispatched.
Another way to listen to events is via an event subscriber. An event
subscriber is a PHP class that's able to tell the dispatcher exactly
which events it should subscribe to. It implements the
EventSubscriberInterface interface, which requires a single static
method called getSubscribedEvents().
See the example here :
https://symfony.com/doc/3.3/components/event_dispatcher.html
The question is a bit long since it's conceptual. I hope it's not a bad read :)
I'm working in a performance critical Spring MVC/Tiles web-app (10,000 users typical load). We load an update employee screen, where we load an employee details screen (bound to an employee business object) for updates via a MultiActionController. There are multiple tabs on this screen, but only tab1 has the updatabale data. Rest of the tabs are read-only stuff, for reference basically.
Needless to say, we've decided to load these read-only tabs in a lazy manner, i.e., when each tab is activated, we fire an ajax call (one-time) for fetch the data from the server. We don't load everything via the update view loading method. Remember: this is one time, read-only data.
Now, I'm in a dilemma. I've made another multiaction controller, named "AjaxController" for handling these ajax calls. Now, my questions:
What should be the best scope for this controller?
Thoughts: If I make it request scoped, then 10,000 users together can create 10,000 instances of this bean: memory problem there. If I make it session scoped, then one will be created per user session. That means, when 10,000 users log in to the app, regardless of whether they hit the AjaxController methods, they will each have a bean in possession.
Then, is singleton the best scope for this controller?
Thoughts: A singleton bean will be created when spring boots, and this very instance will be provided throughout. Sounds good.
Should the handler methods (like fetchTab7DataInJsonFormat) be static and attached to the class?
Thoughts: In this case, can havign static methods semantically conflict with the scope? For example: does scope="session"/"request" + static methods make sense? I ask because even though each user session has its own AjaxController bean, the handler methods are actually attached to the class, and not the instances. Also, does scope="singleton" + static handler methods make sense?
Can I implement the singleton design pattern into AjaxController manually?
Thoughts: What if I control the creation: do the GoF singleton basically. Then what can the scope specification do? Scope session/request surely can't create multiple instances can they?
If, by whatever mechanism (bean specification/design pattern/static methods), I do manage to have one single instance of AjaxController: Will these STATIC methods need to be synchronized? I think not, because even if STATIC handler methods can talk to services (which talk to DB/WS/MQ etc.) which take time, I think each request thread entering the static methods will be returned by their thread Id's right? It's not like user1 enters the static method, and then user2 enters the static method before user1 has been returned, and then they both get some garbled data? This is probably silly, but I want to be sure.
I'm confused. I basically want exactly one single instance of the controller bean servicing all requests for all clients.
Critical Note: The AjaxController bean is not INJECTED anywhere else, it exists isolated. It's methods are hit via ajax calls.
If I were doing this, I would definitely make the LazyLoadController singleton without having static methods in it and without any state in it.
Also, you definitely shouldn't instantiate singletons manually, it's better to use Spring's common mechanism and let the framework control everything.
The overall idea is to avoid using any static methods and/or persistent data in controllers. The right mechanism would be use some service bean for generating data for request, so controller acts as request parameter dispatcher to fetch the data out into the view. No mutable state or concurrently unsafe stuff should be allowed in controller. If some components are user-specific, Spring's AOP system provides injection of the components based on session/request.
That's about good practice in doing thing like that. There's something to clarify to give more specific answer for your case. Did I understand it right that typical use case for will be that AjaxController will pass some of requests to LazyLoadController to get tab data? Please provide details about that in comment or your question, so I may update my answer.
The thing that is wrong with having static methods in controller is that you have to manage concurrent safety by yourself which is not just error-prone but will also reduce overall performance. Spring runs every request in its own thread, so if two concurrent calls need to use some static method and there are shared resources (so you need to use synchronize statement or locks), one of threads will have to wait for another one to complete working in protected block. From the other hand, if you use stateless services and avoid having data that may be shared for multiple calls, you get increased performance and no need to deal with concurrent data access.