Enabling caching for GWT RPC asynchronous calls - gwt

I'm thinking of introducing some kind of caching mechanism (like HTML5 local storage) to avoid frequent RPC calls whenever possible. I would like to get feedback on how caching can be introduced in the below piece of code without changing much of the architecture (like using gwt-dispatch).
void getData() {
/* Loading indicator code skipped */
/* Below is a gwt-maven plugin generated singleton for SomeServiceAsync */
SomeServiceAsync.Util.getInstance().getDataBySearchCriteria(searchCriteria, new AsyncCallback<List<MyData>>() {
public void onFailure(Throwable caught) {
/* Loading indicator code skipped */
Window.alert("Problem : " + caught.getMessage());
}
public void onSuccess(List<MyData> dataList) {
/* Loading indicator code skipped */
}
});
}
One way I can think of to deal with this is to have a custom MyAsyncCallback class defining onSuccess/onFailure methods and then do something like this -
void getData() {
AsyncCallback<List<MyData>> callback = new MyAsyncCallback<List<MyData>>;
// Check if data is present in cache
if(cacheIsPresent)
callback.onSuccess(dataRetrievedFromCache);
else
// Call RPC and same as above and of course, update cache wherever appropriate
}
Apart from this, I had one more question. What is the maximum size of storage available for LocalStorage for popular browsers and how do the browsers manage the LocalStorage for different applications / URLs? Any pointers will be appreciated.

I suggest to add a delegate class which handles the caching. The delegate class could look like this:
public class Delegate {
private static SomeServiceAsync service = SomeServiceAsync.Util.getInstance();
private List<MyData> data;
public static void getData(Callback callback) {
if (date != null) {
callback.onSuccess(data);
} else {
service.getData(new Callback() {
public onSuccess(List<MyData> result) {
data = result;
callback.onSuccess(result);
});
}
}
}
Of course this is a crude sample, you have to refine the code to make it reliable.

I did take too long to decide on using hash maps to cache results.
My strategy was not to use a singleton hashmap, but a singleton common objects class storing static instances of cache. I did not see the reason to load a single hashmap with excessive levels of hashtree branching.
Reduce the amount of hash resolution
If I know that the objects I am dealing with is Employee, Address, Project, I would create three static hashes
final static private Map<Long, Employee> employeeCache =
new HashMap<Long, Employee>();
final static private Map<Long, Address> addressCache =
new HashMap<Long, Address>();
final static private Map<String name, Project> projectCache =
new HashMap<String name, Project>();
public static void putEmployee(Long id, Employee emp){
employeeCache.put(id, emp);
}
public static Employee getEmployee(Long id){
return employeeCache.get(id);
}
public static void putEmployee(Long id, Address addr){
addressCache.put(id, addr);
}
public static Address getEmployee(Long id){
return addressCache.get(id);
}
public static void putProject(String name, Address addr){
projectCache.put(name, addr);
}
public static Address getProject(String name){
return projectCache.get(name);
}
Putting it all in a single map would be hairy. The principle of efficient access and storage of data is - the more information you have determined about the data, the more you should exploit segregating that data using that information you have. It would reduce the levels of hash resolution required to access the data. Not to mention all the risky and indefinite type casting that would need to be done.
Avoid hashing if you can
If you know that you always have a single value of CurrentEmployee and NextEmployee,
avoid storing them in the hash of Employee. Just create static instances
Employee CurrentEmployee, NextEmployee;
That would avoid needing any hash resolution at all.
Avoid contaminating the global namespace
And if possible, keep them as class instances rather than static instances, to avoid contaminating the global namespace.
Why avoid contaminating the global namespace? Because, more than one class would inadvertently use the same name causing untold number of bugs due to global namespace confusion.
Keep the cache nearest to where it is expected or used
If possible, if the cache is mainly for a certain class, keep the cache as a class instance within that class. And provide an eventbus event for any rare instance that another class would need to get data from that cache.
So that you would have an expectable pattern
ZZZManager.getZZZ(id);
Finalise the cache if possible,
otherwise/and privatise it by providing putters and getters. Do not allow another class to inadvertently re-instantiate the cache, especially if one day your class becomes a general utility library. Also putters and getters have the opportunity to validate the request to avoid a request from wiping out the cache or pushing the app into an Exception by directly presenting the cache with keys or values the cache is unable to handle.
Translating these principles into Javascript local storage
The GWT page says
Judicious use of naming conventions can help with processing storage data. For example, in a web app named MyWebApp, key-value data associated with rows in a UI table named Stock could have key names prefixed with MyWebApp.Stock.
Therefore, supplementing the HashMap in your class, with rather crude code,
public class EmployeePresenter {
Storage empStore = Storage.getLocalStorageIfSupported();
HashMap<Long, Employee> employeeCache;
public EmployeePresenter(){
if (empStore==null) {
employeeCache = new HashMap<Employee>();
}
}
private String getPrefix(){
return this.getClass()+".Employee";
//return this.getClass().getCanonicalName()+".Employee";
}
public Employee putEmployee(Long id, Employee employee)
if (empStore==null) {
stockStore.setItem(getPrefix()+id, jsonEncode(employee));
return;
}
employeeCache.put(id, employee);
}
public Employee getEmployee(Long id)
if (empStore==null) {
return (Employee) jsonDecode(Employee.class, stockStore.getItem(getPrefix()+id));
}
return employeeCache(id);
}
}
Since, the localstore is string based only, I am presuming that you will be writing your own json encoder decoder. On the other hand, why not write the json directly into the store the moment you receive it from the callback?
Memory constraints?
I cannot profess expertise in this question but I predict the answer for hashmaps to be the maximum memory constrained by the OS on the browser. Minus all the memory that is already consumed by the browser, plugins and javascript, etc, etc overhead.
For HTML5 local storage the GWT page says
"LocalStorage: 5MB per app per browser. According to the HTML5 spec, this limit can be increased by the user when needed; however, only a few browsers support this."
"SessionStorage: Limited only by system memory"

Since you are using gwt-dispath an easy solution here is to cache the gwt-dispatch Response objects agains the Request objects as a key in a Map. Its easy to implement and type agnostic. You will need to override Request - equals() method to see if the Request is already in the cache. If yes return Response from cache otherwise hit the server with a call.
IMO - LocalStorage is not a necessity here if all you need is in session cache for performance. Local Storage only a must for offline apps.
You may look into this - http://turbomanage.wordpress.com/2010/07/12/caching-batching-dispatcher-for-gwt-dispatch/

Related

Why are static GWT fields not transferred to the client?

ConfigProperty.idPropertyMap is filled on the server side. (verified via log output)
Accessing it on the client side shows it's empty. :-( (verified via log output)
Is this some default behaviour? (I don't think so)
Is the problem maybe related to the inner class ConfigProperty.IdPropertyMap, java.util.HashMap usage, serialization or some field access modifier issue?
Thanks for your help
// the transfer object
public class ConfigProperty implements IsSerializable, Comparable {
...
static public class IdPropertyMap extends HashMap
implements IsSerializable
{
...
}
protected static IdPropertyMap idPropertyMap = new IdPropertyMap();
...
}
// the server service
public class ManagerServiceImpl extends RemoteServiceServlet implements
ManagerService
{
...
public IdPropertyMap getConfigProps(String timeToken)
throws ConfiguratorException
{
...
}
}
added from below after some good answers (thanks!):
answer bottom line: static field sync is not implemented/supported currently. someone/me would have to file a feature request
just my perspective (an fallen-in-love newby to GWT :-)):
I understand pretty good (not perfect! ;-)) the possible implications of "global" variable syncing (a dependency graph or usage of annotations could be useful).
But from a new (otherwise experienced Java EE/web) user it looks like this:
you create some myapp.shared.dto.MyClass class (dto = data transfer objects)
you add some static fields in it that just represent collections of those objects (and maybe some other DTOs)
you can also do this on the client side and all the other static methods work as well
only thing not working is synchronization (which is not sooo bad in the first place)
BUT: some provided annotation, let's say #Transfer static Collection<MyClass> myObjList; would be handy, since I seem to know the impact and benefits that this would bring.
In my case it's rather simple since the client is more static, but would like to have this data without explicitely implementing it if the GWT framework could do it.
static variables are purely class variable It has nothing to do with individual instances. serialization applies only to object.
So ,your are getting always empty a ConfigProperty.idPropertyMap
The idea of RPC is not that you can act as though the client and the server are exactly the same JVM, but that they can share the objects that you pass over the wire. To send a static field over the wire, from the server to the client, the object stored in that field must be returned from the RPC method.
Static properties are not serialized and sent over the wire, because they do not belong to a single object, but to the class itself.
public class MyData implements Serializable {
protected String name;//sent over the wire, each MyData has its own name
protected String key;
protected static String masterKey;//All objects on the server or client
// share this, it cannot be sent over RPC. Instead, another RPC method
// could access it
}
Note, however, that it will only be that one instance which will be shared - if something else on the server changes that field, all clients which have asked for a copy will need to be updated

Singleton pattern using PHP

I am trying to create a dynamic navigation class.
class myApp_Helper_Breadcrum{
protected $navigationArray=array();
private static $_instance = null;
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
$this->navigationArray = array();
}
public function popin($popInElement){
array_push($this->navigationArray,$popInElement);
}
public function displayLinks()
{
//print array
}
}
In boostrap I did following
$nlinks=myApp_Helper_Breadcrum::getInstance();
Zend_Registry::set('nlinks',$nlinks);
Now in my controller I am calling as follow
$nlinks= Zend_Registry::get('nlinks');
$nlinks->popin('Home');
$nlinks->displayLinks();
The problem is, even if this class is singleton the constructor is called again and again which makes my array to initialize. what I am trying to achieve is to keep pushing the items in the navigation array as I navigate the site.
Any idea why it is like this in ZF?
PHP isn't running like Java would where you have a JVM to maintain the state of your classes. In Java you can have a singleton behave exactly as you describe, but in PHP all the classes are refreshed with each subsequent call to the web server. So your singleton will stay in place for the duration of that call to the server, but once the response is sent then you start over again on the next call.
If you want to maintain state through successive calls you need to use the $_SESSION to keep track of your state.
EDIT:
My answer above deals with PHP in general and not the Zend Framework specifically. See my comment below.
Try to define your component as below:
class MyApp_Helper_Breadcrum
{
private static $_instance = null; // use private here
public static function getInstance()
{
if (self::$_instance === null) { // use strictly equal to null
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() // use private here
{
// ...
}
// ...
}
I ran into the exact same problem.
The problem is that the persistence of your classes are on the request scope.
And with zend, you can even have multiple requests for a page load.
PHP is a shared nothing architecture; each
request starts in a new process, and at the end of the request, it's all
thrown away. Persisting across requests simply cannot happen -- unless
you do your own caching. You can serialize objects and restore them --
but pragmatically, in most cases you'll get very little benefit from
this (and often run into all sorts of issues, particularly when it comes
to resource handles).
You may want to use Zend_cache, for persistence
Even though this is old, I would like to add my 2 cent.
Zend DOES NOT create a singleton, that persists across multiple requests. Regardless of the interpretation of the ZF documentation, on each request, the whole stack is re-initialized.
This is where your problem comes from. Since bootstrapping is done on each request, each request also re-initializes your helper method. As far as I know, helpers in ZF 1.x CAN'T be singletons.
The only way I see this being implementes ar you want it to be, is using sessions.

Creating an Autofac Lifetimescope that will expire with time

I have a bank/collection which caches instances of objects in memory so that each request doesn't need to go back to the datastore. I'd like Autofac to provide an instance of this bank, but then expire it after x seconds, so that a new instance is created on the next request. I'm having trouble getting my head around setting up a LifetimeScope to achieve this. I've read through this a couple of times. The Bank object is not really subject to a unit of work. It will ideally reside 'above' all units of work, caching objects within and across them.
I'm currently using the approach below, however it isn't working as I'd hoped.
Can someone please point me in the right direction?
....
builder.Register(c =>
{
return new ORMapBank(c.Resolve<IORMapRoot>());
}).InstancePerMatchingLifetimeScope(ExpireTimeTag.Tag());
IContainer container = builder.Build();
var TimedCache= RootScope.BeginLifetimeScope(ExpireTimeTag.Tag());
DependencyResolver.SetResolver(new AutofacDependencyResolver(TimedCache));
....
public static class ExpireTimeTag
{
static DateTime d = DateTime.Now;
static Object tag = new Object();
public static object Tag()
{
if (d.AddSeconds(10) < DateTime.Now)
{
CreateTag();
return tag;
}
private static void CreateTag()
{
tag = new Object();
}
}
Thanks very much in advance.
It is common to use a caching decorator to achieve this kind of behaviour. Assuming your IORMapRoot is responsible for getting the data in question (but it would work the same if ORMapBank) you do the following:
Create a new type, CachingORMapRoot that implements IORMapRoot
Add a constructor that takes the expiry TimeSpan and an instance of the original IORMapRoot implementation.
Implement the members to call the underlying instance and then cache the results accordingly for subsequent calls (implementation will vary on your cache technology).
Register this type in the container as IORMapRoot
This is a very clean way to implement such caching. It also makes it easy to switch between cached and non-cached implementations.

GWT RequestFactory and multiple types

My GWT app has ten different kinds of entities. Right now I use plain old DTOs and transport them over GWT-RPC. This works well for cases like startup - I can pack them all into a single request.
I'm looking at switching to RequestFactory because there are many times throughout the lifetime of the app (30 minutes, on average) when I just have to update one type of entity, and the unifying/bandwidth-saving features of RequestFactory are appealing. BUT: I don't see a way to download all of my initialization data in a single request when the app loads. I don't want to have to make ten requests to fetch all of the init data for my ten entity types.
Is there a way to make a GeneralRequestContext, or something? I'd even be happy with a solution like:
public interface InitDataProxy extends EntityProxy
{
public UserProxy getInitUsers();
public OrganizationProxy getInitOrganizations();
...
}
public interface GeneralRequestContext extends RequestContext
{
Request<InitDataProxy> getInitData();
}
But this won't work because I don't want to have to actually back InitDataProxy with anything, I just want to use it to combine a bunch of different types of Proxies in a single request.
So: Is there a way to receive multiple, unrelated types of EntityProxy in a single request?
I would also be happy enough making a normal gwt-rpc request to go outside of RequestFactory for this data, but I don't want to have to implement duplicate DTOs to run next to RequestFactory's proxies, and write custom code to copy the DTOs into them!
The InitDataProxy could extend ValueProxy instead, which doesn't require that the object on the server have any kind of id or version semantics. The domain-side InitData type could be an interface, possibly implemented with an anonymous type.
interface InitData {
User getUser();
Organization getOrgatization();
}
class InitService {
static InitData makeInitData() {
return new InitData() { ..... };
}
}
#ProxyFor(InitData.class)
interface InitDataProxy extends ValueProxy {
UserProxy getUser();
OrganizationProxy getOrganization();
}
#Service(InitService.class)
interface Init extends RequestContext {
Request<InitDataProxy> makeInitData();
}

Are singletons automatically persisted between requests in ASP.NET MVC?

I have a lookup table (LUT) of thousands integers that I use on a fair amount of requests to compute stuff based on what was fetched from database.
If I simply create a standard singleton to hold the LUT, is it automatically persisted between requests or do I specifically need to push it to the Application state?
If they are automatically persisted, then what is the difference storing them with the Application state?
How would a correct singleton implementation look like? It doesn't need to be lazily initialized, but it needs to be thread-safe (thousands of theoretical users per server instance) and have good performance.
EDIT: Jon Skeet's 4th version looks promising http://csharpindepth.com/Articles/General/Singleton.aspx
public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
// randomguy's specific stuff. Does this look good to you?
private int[] lut = new int[5000];
public int Compute(Product p) {
return lut[p.Goo];
}
}
Yes, static members persists (not the same thing as persisted - it's not "saved", it never goes away), which would include implementations of a singleton. You get a degree of lazy initialisation for free, as if it's created in a static assignment or static constructor, it won't be called until the relevant class is first used. That creation locks by default, but all other uses would have to be threadsafe as you say. Given the degree of concurrency involved, then unless the singleton was going to be immutable (your look-up table doesn't change for application lifetime) you would have to be very careful as to how you update it (one way is a fake singleton - on update you create a new object and then lock around assigning it to replace the current value; not strictly a singleton though it looks like one "from the outside").
The big danger is that anything introducing global state is suspect, and especially when dealing with a stateless protocol like the web. It can be used well though, especially as an in-memory cache of permanent or near-permanent data, particularly if it involves an object graph that cannot be easily obtained quickly from a database.
The pitfalls are considerable though, so be careful. In particular, the risk of locking issues cannot be understated.
Edit, to match the edit in the question:
My big concern would be how the array gets initialised. Clearly this example is incomplete as it'll only ever have 0 for each item. If it gets set at initialisation and is the read-only, then fine. If it's mutable, then be very, very careful about your threading.
Also be aware of the negative effect of too many such look-ups on scaling. While you save for mosts requests in having pre-calculation, the effect is to have a period of very heavy work when the singleton is updated. A long-ish start-up will likely be tolerable (as it won't be very often), but arbitrary slow downs happening afterwards can be tricky to trace to their source.
I wouldn't rely on a static being persisted between requests. [There is always the, albeit unlikely, chance that the process would be reset between requests.] I'd recommend HttpContext's Cache object for persisting shared resources between requests.
Edit: See Jon's comments about read-only locking.
It's been a while since I've dealt with singleton's (I prefer letting my IOC container deal with lifetimes), but here's how you can handle the thread-safety issues. You'll need to lock around anything that mutates the state of the singleton. Read only operations, like your Compute(int) won't need locking.
// I typically create one lock per collection, but you really need one per set of atomic operations; if you ever modify two collections together, use one lock.
private object lutLock = new object();
private int[] lut = new int[5000];
public int Compute(Product p) {
return lut[p.Goo];
}
public void SetValue(int index, int value)
{
//lock as little code as possible. since this step is read only we don't lock it.
if(index < 0 || index > lut.Length)
{
throw new ArgumentException("Index not in range", "index");
}
// going to mutate state so we need a lock now
lock(lutLock)
{
lut[index] = value;
}
}