I am exploring Reactive UI. I have an ObservableCollection of models in which objects are added at a very high speed. I handle the collectionchanged event and add viewModels for each model in another ObservableCollection.
Can we suppress the CollectionChanged event for Model list and raise an event for a bunch of records or after a specified time interval has lapsed?
Yes, here's how to do it:
using (someReactiveCollection.SuppressChangeNotifications()) {
// TODO: Add a bunch of items
}
Related
I want to implement a Axon projection providing a subscription query. The projection persists entities of a specific based on the events (CRUD). The following should happen if a replay of the projection is executed:
Inform about a empty collection via the subscription query.
Process the events until the projection catches up with the event store.
Inform about the current state of the entities via the subscription query.
My intention is that the subscription query should not inform about many events in a very short time and I want to prevent informing about many intermediate positions (e.g. create and delete a specific entity, it should not be used in the subscription query, because it is not available after catching up).
Currently I cannot implement the third step, because I miss a hook for reacting to the moment when the Axon projection is catching up again.
I use Axon v4.5 and Spring Boot v2.4.5.
At the moment, the Reference Guide is sadly not extremely specific on how to achieve this. I can assure you though that work is underway to improve the entire Event Processor section, including a clearer explanation of the Replay process and the hooks you have.
However, the possible hooks are stated as it is (you can find them here).
What you can do to know whether your event handlers are replaying yes/no, is to utilize the ReplayStatus enumeration. This enum can be used as an additional parameter to your #EventHandler annotated method, holding just two states:
REPLAY
REGULAR
This enumeration allows for conditional logic within an event handler on what to do during replays. If an event handler for example not only updates a projection but also sends an email, you'd want to make sure the email isn't sent again when replaying.
To further clarify how to use this, consider the following snippet:
#EventHandler
public void on(SomeEvent event, ReplayStatus replayStatus) {
if (replayStatus == REGULAR) {
// perform tasks that only may happen when the processor is not replaying
}
// perform tasks that can happen during regular processing and replaying
}
It's within the if-block where you could invoke the QueryUpdateEmitter, to only emit updates when the event handler is performing the regular event handling process.
Say I have a TodoStore. The TodoStore is responsible for keeping my TODO items. Todo items are stored in a database.
I want to know what is the recommended way for loading all todo items into the store and how the views should interact with the store to load the TODO items on startup.
The first alternative is to create a loadTodos action that will retrieve the Todos from the database and emit a TODOS_LOADED event. Views will then call the loadTodos action and then listen to the TODOS_LOADED event and then update themselves by calling TodoStore.getTodos().
Another alternative is to not have a loadTodos action, and have a TodoStore.getTodos() that will return a promise with the existing TODO items. If the TodoStore has already loaded the TODO items, it just returns them; if not, then it will query from the database and return the retrieved items. In this case, even though the store now has loaded the TODO items, it will not emit a TODOS_LOADED event, since getTodos isn't an action.
function getTodos() {
if (loaded)
return Promise.resolve($todoItems);
else
return fetchTodoItemsFromDatabase().then(todoItems) {
loaded = true;
$todoItems = todoItems;
return $todoItems;
});
}
I'm sure many will say that that breaks the Flux architecture because the getTodos function is changing the store state, and store state should only be changed though actions sent in from the dispatcher.
However, if you consider that state for the TodoStore is the existing TODO items in the database, then getTodos isn't really changing any state. The TODO items are exactly the same, hence no view need to be updated or notified. The only thing is that now the store has already retrieved the data, so it is now cached in the store. From the View's perspective, it shouldn't really care about how the Store is implemented. It shouldn't really care if the store still needs to retrieve data from the database or not. All views care about is that they can use the Store to get the TODO items and that the Store will notify them when new TODO items are created, deleted, or changed.
Hence, in this scenario, views should just call TodoStore.getTodos() to render themselves on load, and register an event handler on TODO_CHANGE to be notified when they need to update themselves due to a addition, deletion, or change.
What do you think about these two solutions. Are they any other solutions?
The views do not have to be the entities that call loadTodos(). This can happen in a bootstrap file.
You're correct that you should try your best to restrict the data flow to actions inside the dispatch payload. Sometimes you need to derive data based on the state of other stores, and this is what Dispatcher.waitFor() is for.
What is Flux-like about your fetchTodoItemsFromDatabase() solution is that no other entity is setting data on the store. The store is updating itself. This is good.
My only serious criticism of this solution is that it could result in a delay in rendering if you are actually getting the initial data from the server. Ideally, you would send down some data with the HTML. You would also want to make sure to call for the stores' data within your controller-views' getInitialState() method.
Here is my opinion about that, very close to yours.
I maintain the state of my application in Store via Immutable.Record and Immutable.OrderedMap from Immutable.js
I have a top controller-view component that get its state from the Store.
Something such as the following :
function getInitialState() {
return {
todos: TodoStore.getAll()
}
}
TodoStore.getAll methods will retrieve the data from the server via a APIUtils.getTodos() request if it's internal _todos map is empty. I advocate for read data triggered in Store and write data triggered in ActionCreators.
By the time the request is processing, my component will render a simple loading spinner or something like that
When the request resolves, APIUtils trigger an action such as TODO_LIST_RECEIVE_SUCCESS or TODO_LIVE_RECEIVE_FAIL depending on the status of the response
My TodoStore will responds to these action by updating its internal state (populating it's internal Immutable.OrderedMap with Immutable.Record created from action payloads.
If you want to see an example through a basic implementation, take a look to this answer about React/Flux and xhr/routing/caching .
I know it's been a couple of years since this was asked, but it perfectly summed up the questions I am struggling with this week. So to help any others that may come across this question, I found this blog post that really helped me out by Nick Klepinger: "ngrx and Tour of Heroes".
It is specifically using Angular 2 and #ngrx/store, but answers your question very well.
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
I have an object that is updated from a polling loop on a thread. This object fires particular events when data changes, etc.
I'm trying to use this object in conjunction with a windows form, where I create event handlers on the form to update the UI. Of course, this causes cross-thread operation exceptions if I try to manipulate the UI directly in these handlers.
I can get it to work by going through the standard procedure of checking InvokeRequired, using a delegate, blah blah blah. But I want to publish this object as a library, and I don't want end-users to have to worry about all that.
I want my object to somehow take care of synchronizing those event callbacks with the form so that end-users can manipulate the UI elements in those handlers worry-free.
Is there a way to do this??
If your object is always related to a single form, there is a simple trick indeed. The important fact here is, that you instanciate your object from the thread you like to affect the form later.
The trick is to instanciate a simple Control (new Control()) in your object in the constructor. When you perform logic on your form, use the Invoke/BeginInvoke methods on this simple control, to dispatch the action to the correct calling thread. So you have the dispatching logic directly in your object and there is no need for other users of your object to take care about this.