Apollo cache-and-network policy always bypasses the cache - caching

Using Apollo Client 3.6.9 and generated React query hooks (from codegen) I see this strange behaviour where a component uses cache as expected whenever no fetchPolicy is provide (and it's using the default "cache-first" policy), but if I change it to have fetchPolicy "cache-and-network", it totally bypasses the cache when a new component is mounted. With no exception, it renders the first time with no data, and then it renders again with the data, so it's actually equivalent to just doing "network-only", which is not what I'm looking for. I've tried downgrading to other 3.x.x versions of Apollo client to see if it was a temporary glitch, but all versions act the same. Am I missing something here?

Related

Getting the request body of search response with 2.X NEST client

I'm using the new 2.X NEST client. That part is important, because there were a great many breaking changes which will effect potential answers here.
Previously, I used the Glimpse Elasticsearch plugin to see the underlying queries being generated by NEST. However, it would appear that that plugin is no longer compatible with 2.X NEST. As a result, I'm trying to find a workaround to see the JSON query. The problem here is that the old way of accessing response.RequestInformation to get at the request body is gone. It seems to have been replaced with a combination of ApiCall, CallDetails, and DebugInformation. The problem here is that in all of these the request byte array is null unless you add .DisableDirectStreaming() to the ConnectionSettings instance you pass into ElasticClient. The problem there is that I'm handling all that using dependency injection with Ninject, so in something like a controller action, I have no access to the ConnectionSettings instance to make such a change. I suppose I could just add .DisableDirectStreaming() globally, but I have no idea what the potential consequences of that is and the documentation on this is frustratingly sparse.
So, there's a few avenues for an answer here, any of which I'll accept. First, if anyone has manage to get the Glimpse plugin functioning with 2.X, I'd love to know what you did. However, based on the fact that the underlying API has changed dramatically, my assumption is that the plugin is fundamentally broken until someone branches it for 2.X or Elastic comes out with their own version (which is supposedly coming at some undetermined point in the future).
Second, if there's some way to get at the request body without disabling direct streaming, and I simply missed it. I'd appreciate guidance there.
Third, if anyone has any ideas for how I can disable direct streaming at the controller action level, without affecting my Ninject setup or applying it globally, feel free to chime in.
Finally, it would be great if someone from the Elastic team can enlighten me to the effects of disabling direct streaming and what potential problems can arise from that, so I can make a determination about whether it would be wise to apply it globally or not.
With .DisableDirectStreaming() set to true, the request bytes and response bytes are buffered in memory streams to enable them to be available on the response via response.RequestBodyInBytes and response.ResponseBodyInBytes, respectively.
By default, it is set to false so the request type e.g. SearchDescriptor<T>, SearchRequest<T>, etc. is serialized directly to the request stream of the http request and similarly, the response type is deserialized from the response stream. The overhead of setting it to true is therefore keeping the request and response bytes around in memory for the lifetime of the response (and GC kicking in).
With Connection Settings, it's best to have one instance for the lifetime of the application; Serialization settings are cached per connection settings as well as caches for field and property expressions. There's no way currently to keep the request and response bytes around on a per request basis i.e. ad-hoc introspection, but I think this would be a useful addition; I'll add an issue for it :)
I'm not personally overly familiar with the Glimpse integration but I would expect it would require updating to work with NEST 2.x because of some of the changes. Having just given it a brief look, the changes look pretty straightforward. Looks like this can be done without having to set .DisableDirectStreaming() to true, but only grabbing the request bytes before they're written to the request stream.

Cache for Angular2

I am looking for a cache implementation for an Angular2 application.
For example, we have a million Movie objects stored on a server (i.e. enough that we don't want to grab them all at once). On the server, a REST endpoint is available : getMovie(String id)
Back on the client side, the cache should provide a simple way to get a movie from Angular, something like cache.getMovie(id:string): Observable<Movie>. This will hit the REST endpoint only for the first call, and store it locally for later requests.
Angular1 has angular-cache or the $cacheFactory, with LRU support and other great functionalities.
I started implementing a basic cache using a local HashMap, but that seems like a very common need.
Is there a good in-memory cache implementation for Angular2 yet?
I would use lscache and extend it providing few underlying storages: localStorage, sessionStorage, and self-implmented memoryStorage. TypeScript definitions are already available.

How to add information to Glimpse after EndRequest?

I'm the maintainer of the Miniprofiler Glimpse plugin and with the latest Miniprofiler versions I'm not able to push data to Glimpse because the Profiler is not yet populated (in previous versions it was) when the GetData() method of the tab is called.
Right now what I do is wrap the Miniprofiler Storage and when the Save() method is called, all the needed information is there but it's too late and I don't know how to send it to the tab.
So, what is the best approach (if possible) to add this information to a tab when it's ready in Miniprofiler?
Unfortunately EndRequest is currently the last moment you can subscribe on to return the necessary data. That is the moment when Glimpse will finalize its monitoring for the given request and the moment it will persist that information to the persistence store.
Although in v1 it is possible to add data after the EndRequest but only when using the default in memory store. So you could return your wrapper, which will be empty at that moment, and it will be stored in memory, allowing you to change the wrapped content afterwards.
But the above will not work for other persistence stores. We might also change this in v2 to make it deterministic, independent of the persistence store being used.
Maybe you could have your wrapper ask MiniProfiler to calculate the results at that moment, so they can be stored, even though those results might not be 100% complete?

Sessions in Meteor

After a research it seems that Meteor Sessions are reset after refreshing page or opening the website in new tab, i.e. they are not usual server-side sessions but something like global javascript variables on client-side. Some people advice to use AmplifyJS, but I'm not sure that it will work like usual session in other frameworks/languages and also it is a third party library, so is there any normal way to use sessions in Meteor, i.e. keep user-specific data on server?
At this moment I'm handling that by using custom Collections, but it is not an ideal way of doing that because it is needed to remove expired values from Collection manually, which makes additional troubles.
Yes this is correct. Despite the name Session is nothing like a cookie, but just a reactive form of a variable stored in a hashmap
To keep data persistent across tabs you need to use a Collections (as this is the only way to reactively share data across tabs) - Cookies can't work because they can't be made reactive as data needs to be sent to the server to notify the client when there is a change. There really wouldn't be another way at the moment as the publish/subscribe methods can only send down data from collections at the moment.
You can use your setup you have now with your custom collection. You can use a server side cron job to remove expired data (either with Meteor.setInterval or Tom Coleman's cron.
There is a package developed just for that: https://atmospherejs.com/u2622/persistent-session
After installation you can use the following functions to set sessions which are persistent:
//store a persistent session variable which is stored across templates
Session.setPersistent(key, value);
//same as above, but automatically deletes session data when user logs out
Session.setAuth(key, value);
I've tried the package and it works like charm.

Webfont Loader & Google JSAPI Cannot load together?

I'm not sure why, though getting a similar issue.
Trying to load in a font from fonts.com with webfontloader so I can call functions after they're loaded.
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js"></script>
<script>
WebFont.load({
monotype: {
projectId: 'xxxxxxxxxxxxxxxxxxxx'
},
active: function() {
mainNav();
}
});
But when ever I include it WITH the jsapi
<script src="https://www.google.com/jsapi"></script>
I get the following issue in the console:
Uncaught TypeError: Cannot call method 'hasAttribute' of null
Yet if loaded in separately, they're fine...
Any ideas?
Try using the following url to load the webfonts api:
<script src="//ajax.googleapis.com/ajax/libs/webfont/1.1.2/webfont.js"></script>
Check the following post for more details: https://groups.google.com/forum/#!msg/google-ajax-search-api/dWVzQF_YWCM/Y3-R738wh78J
We no longer support partial version aliases for new versions of
libraries. Any partial version aliases already in place will continue
to be supported and updated. The reason is that URLs like
https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js
which is saying "give me the most recent version of jquery 1.x.x) have
very short cache lifetimes since the most recent version can change at
any time. This is bad for performance. This is also bad for your web
site, in the event that a library makes breaking changes in its APIs
between versions that cause your page to suddenly render differently.
Libraries do not usually make such changes intentionally but pages
sometimes depend on behavior of an unspecified corner case of an API
that may be changed intentionally or inadvertently as the library is
updated.
So we strongly recommend that you specify the complete version string
when referencing libraries hosted on the Google AJAX APIs. You can
always find the most recent version at
https://developers.google.com/speed/libraries/devguide. In this case,
the most recent 1.9.x version is currently 1.9.1 so we suggest using
the URL
https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js
to get a stable version and better caching.
(Also, your example above doesn't have a closing </script> tag. Just want to verify this doesn't exist in your own code).

Resources