Cross posted from JBoss Infinispan Discussions
I'm trying to implement some code that takes actions whenever an entry is created in one of my Infinispan caches. I realized quickly that the CacheEntryCreatedEvent object delieved to my #CacheEntryCreated method does not contain the newly created entry so I went searching for a solution.
I found various discussions about the problem with the solution being to catch the #CacheEntryModified event that is delivered after the #CacheEntryCreated event and take the object when the isPre()=false. However, I think I missed something because in all the disucssions none address the situation where you have a modification event that represent a elgitimate modification of an existing entry and not a creation.
Does this mean that my #Listener object has to maintain state information between the delivery of events? My #CacheEntryModified has to integate the event object, determine its a create event (i.e. getValue() == null && isPre() == true) and then wait for the next #CacheEntryModified event before grabbing the newly created object?
This bring up the obvious question of what to do if another #Listener object vetoes the modification before the second #CacheEntryModified (i.e. isPre() == false) event is delivered?
How do other peopel handle this situation?
I suppose the best way to do it now is with a ThreadLocal in your listener.
The future 5.3.0 release will improve this a lot, CacheEntryCreatedEvent will have a getValue() method and CacheEntryModifiedEvent will have a isCreated() method: https://github.com/infinispan/infinispan/commit/1aa2554e1c5ea46318402975de946f2e9ea44442#diff-22
Related
I am investigating a use case where ignite has to listen to changes of a property of an object in the data grid and do some operations on that object. For performance, I want the processing to be done on the same node where the data is.
How can I get an event when the property of a object has changed to a specific value (eg. Object 'X' has a property 'state' which is set to 'scheduled' from 'created') and make sure that only events are taken from the node where the object lives in?
How can I make sure that when I got the event and start processing it, nobody else changes the object (only read is allowed) until processing is finished (in other words, a transaction starts as soon as the event is picked up)?
How can I make sure that the processing code is deployed to all nodes (processing is stateless) and that it only operates on local data (without having a hard link between data object and code, in other words, if the processing code is updated in the future, the objects stay untouched)
What I got from the docs is the following:
// Local listener that listenes to local events.
IgnitePredicate<CacheEvent> locLsnr = evt -> {
// CODE
return result;
};
// Subscribe to specified cache events occuring on local node.
ignite.events().localListen(locLsnr,
EventType.EVT_CACHE_OBJECT_PUT);
In the CODE block; I have to check for a state change on 'evt.newValue()', can't that be done earlier? Ie. as a paremeter to localListen somehow?
In the CODE block, is the Object locked until I return the result? In other words, is it in here that I am sure nobody can changes the object and that I can safely change my Object? IMO it is a strange place to do that in a 'Predicate' definition and not in a handler class.
Sven
Sven,
Your code looks correct and should work as you expect. Answering your questions:
Event listener is called right after the value is updated, so I think it's OK to check the field you're interested in inside the listener. If the field is not changed, just return right away.
The object is locked, because listener is called inside the sync block for the entry. You can modify the same object, but I would not recommend to execute any sync operations like cache updates inside the listener because it's error-prone and can affect performance. You should do this asynchronously, so that the lock is released as soon as possible.
I've spend days trying to find a solution the problem i'm going to try to describe, i've googled alot and even looked at the .NET 4 reference source for SendReply and InternalSendReply activity. But until now i'm stuck.
To make the life of our end customers simpler i want to replace the Receive and SendReply activities with custom activites and use bookmarks instead.
I'm implementing a central webservice which can route to a correct workflow instance, that workflow modifies the bookmark value and finaly it creates a new bookmark while returning the modified bookmark value. It's rather complex already with a WorkflowServiceHostFactory which adds Behaviours and Attach a DataContractResolver to the endpoint.
The endpoint is derived from WorkflowHostingEndpoint which resolves a bookmark created in a custom activity (instead of a receive). And i want another activity instead of a sendreply. Those 2 should correlate and the custom sendreply does send a response on the open channel through the endpoint while creating a new bookmark.
The problem is that i didn't find a way yet to access the endpoint responseContext from within my custom send activity. On the other side, at the workflowcreating endpoint side, it seems that i'm not able to be notified whenever the workflow becomes Idle and as well i don't seem to be able to access the WorkflowExtensions from the host. i'm missing something?
A possible solution i've in mind might be not using a WorkflowServiceHost, but then i loose alot of AppFabric functionaly.
The workflowapplication in platform update 1 has some extension methods called RunEpisode with an overload Func called idleEventCallback. There it's possible to hook into the OnIdle and get a workflowextension to get the object to send back as response.
To answer my own question, i ended up in a workaround using the servicebroker functionality of sql server. The SqlDependency class where the workflow listens for the event to be fired whenever the workflow reach the activity that creates a new bookmark in another state.
Using Ncqrs, is there a way to replay every single event ever happened (all aggregate types) and feed these through my denormalizers in order to recreate the whole read model from scratch?
Edit:
I though it's be good to provide a more specific use case. I'm building this inside a ASP.NET MVC application and using Entity Framework (Code first) for working with the read models. In order to speed up development (and because I'm lazy), I want to use a database initializer that recreates the database schemas once any read model changes. Then using the initializer's seed method to repopulate them.
There is unfortunately nothing built in to do this for you (though I haven't updated the version of ncqrs I use in quite a while so perhaps that's changed). It is also somewhat non-trivial to do it since it depends on exactly what you want to do.
The way I would do it (up to this point I have not had a need) would be to:
Call to the event store to get all relevant events
Depending on what you are doing this could be all events or just the events for one aggregate root, or a subset of events for one or more aggregate roots.
Re-create the read-model in memory from scratch (to save slow and unnecessary writing)
Store the re-created read-model in place of the existing one
Call to the event store one more time to get any events that may have been missed
Repeat until there are no new events being returned
One thing to note, if you are recreating the entire read-model database from scratch I would off-line the service temporarily or queue up new events until you finish.
Again there are different ways you could approach this problem, your architecture and scenarios will probably dictate how best to do it.
We use a MsSqlServerEventStore, to replay all the events I implemented the following code:
var myEventBus = NcqrsEnvironment.Get<IEventBus>();
if (myEventBus == null) throw new Exception("EventBus is not found in NcqesEnvironment");
var myEventStore = NcqrsEnvironment.Get<IEventStore>() as MsSqlServerEventStore;
if (myEventStore == null) throw new Exception("MsSqlServerEventStore is not found in NcqesEnvironment");
var myEvents = myEventStore.GetEventsAfter(GetFirstEventIdFromEventStore(), int.MaxValue);
myEventBus.Publish(myEvents);
This will push all the events on the eventbus and the denormalizers will process all the events. The function GetFirstEventIdFromEventStore just queries the eventstore and returns the first Id from the eventstore (where SequentialId = 1)
What I ended up doing is the following. At the service startup, before any commands are being processed, if the read model has changed, I throw it away and recreate it from scratch by processing all past events in my denormalizers. This is done in the database initializer's seed method.
This was a trivial task using the MS SQL event storage as there was a method for retrieving all events. However, I'm not sure about other event storages.
We are working on a portal environment. On one of our page we have two portlets. When some action happens on one portlet, we have to minimize the other portlet and viceversa.
So we feel that this is a suitable situation where we can use Dojo's publish/subscribe model. But I'm a bit confused if I need to use different topics [One when some action happens on Portlet A, and the second topic when some action occurs on PortletB] or one topic [something like minimize]. Can someone please guide me.
This is really up to you, and depends on your needs.
Topics are free-form texts, so you can arrange it in any text format you like.
My own experiences have been to treat a topic as an "event". Therefore, one topic, one event.
My experience has also been that it is tremendous beneficial to implement "commands" in the same system as events -- so you have a universal command/event system.
Events (therefore topics) do not have to correspond to your portlets. For instance, one portlet can have multiple events (if they make sense), or one event can be shared by multiple portlets (for shared functionalities or for cross-portlet communcations).
Parameters and data can be passed with the event (i.e. topic) as arguments.
Now, a good trick I've learnt is to have "sub-topics" -- i.e. topics that are prefixed with an parent topic, when things want to subscribe to a particular instance of event.
Example: Assume we have an event called "/portlets/showhide" which is published by any portlet when it is shown or hidden, together with the id of the portlet and a boolean variable indicating whether it is shown or hidden.
Now, assume that a portlet will also publish topics called "/portlets/showhide/{id}" (with true/false argument) and "/portlets/showhide/{id}/show" (no arguments) when shown, together with the generic "/portlets/showhide" topic (event).
Now assume some handler object is really only interested when the "xyz" portlet is hidden. It doesn't have to subscribe to "/portlets/showhide" and listen to all those events of other portlets that it is not interested in. It can simply subscribe to "/portlets/showhide/xyz/hide". When number of subscriptions increase in a large system, this kind of optimizations can come in quite handy.
You can use one topic in which pass additional parameters. Something like this:
// PortletA
dojo.publish("onPortletAction", [{sender: "PortletA"}]);
// PortletB
dojo.publish("onPortletAction", [{sender: "PortletB"}]);
....
dojo.subscribe("onPortletAction", dojo.hitch(window, window.processAction));
window.processAction = function(data) {
if (data.sender == "PortletA"){
//to do something
}
if (data.sender == "PortletB") {
//to do something
}
}
I'm working on a small application using C++/wxWidgets, where several parts of the GUI need to be updated based on e.g. received UDP datagrams. More specifically, a secondary thread tries to keep a list of available "clients" in the network (which may come and go away) and e.g. corresponding comboboxes in the UI need to be updated to reflect the changes.
The documentation mentions that for this kind of thing EVT_UPDATE_UI would be a good choice. As far as I can understand from the sparse documentation, this event is sent automatically by the system and provides some support for assisted UI change.
However, I'd feel more comfortable using a more direct approach, i.e. where e.g. a window object could register/subscribe to receive notifications (either events or callbacks) upon particular events and another part of the code is sending out these notifications when required. I could do this in C++ using my own code, however I guess if wxWidgets already supports something like that, I should make use of it. However I haven't found anything in that regards.
So, the question is: does wxWidgets support this kind of notification system (or similar alternatives) or would I be best served coding my own?
AFAIK there is nothing directly usable in wxWidgets, but doing it on your own seems easy.
What I would do:
Create a wxEvtHandler-descendent class to hold the list of available "clients" in the network. Let this class have a wxCriticalSection, and use a wxCriticalSectionLocker for that in all methods that add or delete "clients".
Create a worker thread class by inheriting wxThread to handle your UDP datagrams, using blocking calls. The thread should directly call methods of the client list object whenever a client has to be added or removed. In these methods update the list of clients, and ::wxPostEvent() an event to itself (this will execute the whole notification calls in the main GUI thread).
Handle the event in the client list class, and notify all listeners that the list of clients has changed. The observer pattern seems to me a good fit. You could either call a method of all registered listeners directly, or send a wxCommandEvent to them.
Have you tried calling Update() on the widget(s) that change? Once you update the contents of the combo box, call Update(), and the contents should update.