I'm looking for something similar to RemovalListener/RemovalNotification - but notification of when values in the cache are modified. Notification would include the old value, as well as the new value that has just been added.
[update]
I only populate the cache via a CaceLoader (load & reload). The "source" of the cached elements are at times flakey (remote to the cache).
So the two primary reason for having the replacement element as well are:
Debug logging to indicate when/what values are actually retrieved
from the remote source. This one could be accomplished in a class
that does the remote retrieval.
Generate difference that can then be proactively pushed to (remote)
clients. e.g. publishing changes via blazeDS, rather than requiring
the clients to continuously "get".
It should be possible to implement this without additional notification via the reload method, and getting the current cache contents before going off and getting the new value, and then comparing the new value and the previous value - and then taking additional action. I was looking for a more generic way to decouple the modification notification.
Thanks.
You could file a Guava feature request asking for a method to be added to RemovalNotification that would return the replacement value when the cause is REPLACED. But please provide as much detail as possible about your problem and why this is a good solution for it.
Related
I am looking at the implementation of LogbackMDCAdapter, and it keeps track of lastOperation I don't understand the reason for doing this, anyone has an idea why this is done?
And, why duplicateAndInsertNewMap is required?
Based on the comment here the map copying is required for serialization purposes
Each time a value is added, a new instance of the map is created. This
is to be certain that the serialization process will operate on the
updated map and not send a reference to the old map, thus not allowing
the remote logback component to see the latest changes.
This refers to the behaviour of ObjectOutputStream sending references to previously written objects instead of the full object, unless using the writeUnshared method.
It is not directly obvious why it's possible to skip copying unless there's a get/put combination, but apparently even if you have multiple put operations in a row, the serialization will work properly as long as the map is copied only when a put/remove is performed right after a get. So this is a performance optimization to avoid copying the map unnecessarily when putting several items in it.
I have an android app where I extend the application object as such
public class Globals extends Application {
private Map<String, Object> Creators = new LinkedHashMap<>();
}
Globals has various things in it. usually HashMaps of things - I use it as a global json cache where each Context has an instance of this. Now overnight it appears the Application object can sometimes be empty. i.e. I use the app go away and go to sleep, go back to testing it in the morning and all the json caches are empty. But the user is still "logged in". I assume this is because of garbage collection on the OS.
Now. I could just refresh the json cache or force "logout" when the json cache is empty but there is a problem - it may be empty because there IS legitimately no json from the server. i.e "being empty" is no reason to go get more. What I need to be able to do is detect when android has flattened the cache, or at least know the minimum amount of time that Android will keep the Application extension.
Would it set everything to null?
Has anyone got any ideas? Bear in mind the context will re-initialise null HashMap members of the Application in the context in onCreate (which is required for reason outside the scope) because I declare the new but simply testing for "null" is not really an option. I suppose making a blank null that is changed only on json gather would be ok but I need to KNOW this will work or I lose yet another day chasing this (i.e it's VERY hard to test)
Now overnight it appears the Application object can sometimes be empty. i.e. I use the app go away and go to sleep, go back to testing it in the morning and all the json caches are empty.
Your process was terminated, most likely. See the documentation and the documentation.
What I need to be able to do is detect when android has flattened the cache
You are not informed when your process is terminated.
or at least know the minimum amount of time that Android will keep the Application extension
Your process can be terminated milliseconds after it leaves the foreground.
[Application works] fine as a data store
Only for data that you can easily reload from a persistent data store.
[Application] works works on multi thread
Only if you add your own thread-synchronization logic. There is nothing magic about properties and functions on Application that makes them thread-safe.
where there is no place to store mutable data - this is the best alternative
Any data that you wish to keep should be stored on disk (database, SharedPreferences, or other types of files) or on a server.
so my question remains how to mitigate it
Any data that you wish to keep should be stored on disk (database, SharedPreferences, or other types of files) or on a server. Use in-memory caches as caches.
because things like SQLite are useless they're not thread safe
If you use the same SQLiteDatabase instance for your operations, SQLite is thread-safe.
effectively making it impossible to run anything in parallel
You are certainly welcome to use other persistent data stores if you find SQLite to be distasteful.
recently I dove into the world of JMX, trying to instrument our applications, and expose some operations through a custom JMXClient. The work of figuring out how to instrument the classes without having to change much about our existing code is already done. I accomplished this using a DynamicMBean implementation. Specifically, I created a set of annotations, which we decorate our classes with. Then, when objects are created (or initialized if they are used as static classes), we register them with our MBeanServer through a static class, that builds a dynamicMBean for the class and registers it. This has worked out beautifully when we just use JConsole or VisualVM. We can execute operations and view the state of fields all like we should be able to. My question is more geared toward creating a semi-realtime JMXClient like JConsole.
The biggest problem I'm facing here is how to make the JMXClient report the state of fields in as close to realtime as I can reasonably get, without having to modify the instrumented libraries to push notifications (eg. in a setter method of some class, set the field, then fire off a JMX notification). We want the classes to be all but entirely unaware they are being instrumented. If you check out JConsole while inspecting an attribute, there is a refresh button at the bottom of the the screen that refreshes the attribute values. The value it displays to you is the value retrieved when that attribute was loaded into the view, and wont ever change without using the refresh button. I want this to happen on its own.
I have written a small UI which shows some data about connection states, and a few field on some instrumented classes. In order to make those values reflect the current state, I have a Thread which spins in the background. Every second or so the thread attempts to get the current values of the fields I'm interested in, then the UI gets updated as a result. I don't really like this solution very much, as its tricky to write the logic that updates the underlying models. And even trickier to update the UI in a way that doesn't cause strange bugs (using Swing).
I could also write an additional section of the JMXAgent in our application side, with a single thread that runs through the list of DynamicMBeans that have been registered, determines if the values of their attributes have change, then pushes a notification(s). This would move the notification logic out of the instrumented libraries, but still puts more load on the applications :(.
I'm just wondering if any of you have been in this position with JMX, or something else, and can guide me in the right direction for a design methodology for the JMXClient or really any other advice that could make this solution more elegant than the one I have.
Any suggestions you guys have would be appreciated.
If you don't want to change the entities then something is going to have to poll them. Either your JMXAgent or the JMX client is going to have to request the beans every so often. There is no way for you to get around this performance hit although since you are calling a bunch of gets, I don't think it's going to be very expensive. Certainly your JMXAgent would be better than the JMX client polling all of the time. But if the client is polling all of the beans anyway then the cost may be exactly the same.
You would not need to do the polling if the objects could call the agent to say that they have been changed or if they supported some sort of isDirty() method.
In our systems, we have a metrics system that the various components used. Each of the classes incremented their own metric and it was the metrics that were wired into a persister. You could request the metric values using JMX or persist them to disk or the wire. By using a Metric type, then there was separation between the entity that was doing the counting and the entities that needed access to all of the metric values.
By going to a registered Metric object type model, your GUI could then query the MetricRegistrar for all of the metrics and display them via JMX, HTML, or whatever. So your entities would just do metric.increment() or metric.set(...) and the GUI would query the metric whenever it needed the value.
Hope something here helps.
Being efficient here means staying inside the mbean server that contains the beans you're looking at. What you want is a way to convert the mbeans that don't know how to issue notifications into mbeans that do.
For watching numeric and string attributes, you can use the standard mbeans in the monitor package. Instantiate those in the mbean server that contains the beans you actually want to watch, and then set the properties appropriately. You can do this without adding code to the target because the monitor package is standard in the JVM. The monitor beans will watch the objects you select for changes and will emit change notifications only when actual changes are observed. Use setGranularityPeriod to tell the monitor beans how often to look at the target.
Once the monitor beans are in place, just register for the MonitorNotifications that will be created upon change.
not a solution per se but you can simplify your polling-event translator JMXAgent implementation using spring integration. It has something called JMX Attribute Polling Channel which seems to fulfill your need. example here
I'm working on integrated an application with Exchange using EWS Java. Yes, it's not officially supported, I know. It's all pretty straightforward and I have streaming notifications set up with the exchange server. However, I've hit a couple of snags that are a bit head-scratching.
First, it seems that every event (or batch of events) gets sent twice. For example, if I'm watching the Calendar for Modified events and I create a new appointment or modify an appointment, I'll get two identical notifications, each with an ItemEvent and a FolderEvent. They're definitely distinct objects coming in one right after the other and there is zero difference between the two events. Each object has the same value in any relevant field as the previous. The only difference seems to be the memory address.
Second, I'm hoping to make the notifications a bit more fine-grained. I want to see when a calendar item has been modified, but not when a calendar item is created. It appears that I can only watch the Calendar folder overall and that Modified includes new items. Is there any way to make that more precise?
EDIT: Actually, I found that this only seems to happen with Meetings created in the Calendar folder, and only those with other Attendees. Two NotificationEventArgs, each with a FolderEvent and an ItemEvent. On further inspection, I recently found that one ItemEvent is Created and one is Modified, which isn't terribly surprising to me now knowing how Exchange tends to handle Appointments. The idea was to watch for both created and modified items, although I suppose it could have been broken up into two streaming subscriptions or, given the behavior, set to only modified as that would have captured "new" Appointments anyway.
In any case, this was handled with a periodic SyncFolder (Much was changed between the asking of this and the final design), which worked out well in the end.
Although I dont have experience of working on EWS in Java, Ill try to answer your questions as the concept remains the same. My code references will be from C#
For the first part, the behavior you are experiencing is the expected behavior. When you subscribe to a folder, you get notified on any event that you have specified while creating the subscription takes place. Thus if you have subscribed to the "Calendar" folder for Modified and Create events, and you create or modify an appointment, you will get 2 notifications:
1 for the Folder level changes (FolderEvent): even if you create a new item, the folder has actually been "modified"
1 for the Item level changes (ItemEvent): for the created item
These two are NOT same. They may look similar as both inherit from "NotificationEvent" base class, but are different types.
http://msdn.microsoft.com/en-us/library/office/microsoft.exchange.webservices.data.folderevent(v=exchg.80).aspx
http://msdn.microsoft.com/en-us/library/office/microsoft.exchange.webservices.data.itemevent(v=exchg.80).aspx
For the second part, to see only modified events, select only "EventType.Modified" when you are creating the subscription. It would be good if you can share your code snippet to show how you are subscribing.
I have a List of Java objects on my server which is sent to the client through some serialization mechanism. Once in a while the List of objects gets updated on the server, that is, some objects get added, some get deleted and others just change their place in the List. I want to update the List on the client side as well, but send the least possible data. Especially, I don't want to resend Objects which are already available on the client.
Is there a library available which will produce some sort of diff from the two lists, so that I can only send the difference and the new Objects accross the wire?
I have found several Java implementation of the unix diff command, but this algorithm is unpractical for order changes. ie. [A,B,C] -> [C,B,A] could be sent as only place changes [1->3] [3->1], while diff will want to resend the whole A and C objects (as far as I understand).
I would do this by making the public interface of the objects wherever they are modified silently keep a log of changes made, that is, add an object representing each modification to a list of modifications.
That way you have a minimal list of the exact changes to send to the other machine, rather than needing to infer them using fallible guesswork by comparing old versus new.
To create the object model so that it automatically records changes to itself, you will likely benefit from some code generation or AOP to avoid a lot of repetitive patterns. Methods that set the value of a property, or add/remove from lists, all need to call into a central log shared by the object hierarchy.
You can "pretend" that your list is a string, and use Damerau–Levenshtein distance to find the minimum operations necessary to transform one to another, allowing insertion, deletion, substitution, and transposition (which is what your example suggests).
I'm not aware of a mature and/or stable implementation, and even if one exists, it's likely targeted for strings, so adapting to a list of abstract value types would be a challenge. Implementing your own is also likely to be a challenging task, but it's certainly doable.
JaVers lib (http://javers.org) do the job.
Diff diff = javers.compare(list1, list2);
Diff contains list of changes like: object-added, object-removed, index-changed
For now I'll just send the complete List over the wire but instead of the objects, I use only a unique ID. If the client does not have the object locally, it requests it using the ID.
This is certainly less beautiful than an optimal algorithm but has the expected result: expensive objects are only sent once over the wire.