I have setup an NSURLCache and set the sharedcache to the initialized cache.
I can see the cache size growing when I log the size in the NSURLConnection delegates.
For some reason when requesting the same data, a request is made to the server again, and the log of the cache size shows the log staying the same size.
This indicates to me that the cache is working correctly, but for some reason the URL Loader is not pulling from the cache.
I use the default cache policy on the requests and have double checked the headers in the response.
After reading around on here I see other people mentioning the same issue and setting the memory capacity and disk capacity to the same value solves their issue, but it does not work for me. New requests are being made every time rather than pulling from the cache.
Would it be wise to instead check the cache for the data before making the request? I dont see the point of the cachingPolicy parameter to the NSURLRequest method.
well HTTP also lets the server tell you how to cache - it can disallow caching (and also set a max. cache time)
that may influence SDURLCache
anyways, also look at UIWebView and NSURLCache have a troubled relationship
there it is said that UIWebView doesnt work
Related
I am adding caching to an API server. The implementation of the caching system of the framework I am using simply hashes the whole URL of the request and uses it as a cache key (as well as some other data like language, etc..).
But with this simple system I can add fake query parameters to the url with arbitrary values and my system will also cache those requests. For example:
GET https://example.com/apicall # Cached
GET https://example.com/apicall?fake=1 # Also cached
GET https://example.com/apicall?fake=2 # Also cached!
Is this something I should worry about? That people can very easily fill my cache with junk entries that aren't used? Or am I exaggerating the potential impact of this?
I'm using ImageResizer + Diskcache plugin and I'm finding issues to get cache working properly. Either the images are cached forever (regardless how many times I upload a new image) or changing some settings I get the old image in some browsers/computers and the new one in others.
This is what I have now in my web.config:
<add name="AzureReader2" connectionString="blahblahblah" endpoint="http://blahblahblah.blob.core.windows.net/" prefix="~/" redirectToBlobIfUnmodified="false" requireImageExtension="false" checkForModifiedFiles="true" cacheMetadata="true"/>
and:
<diskcache dir="~/imagecache" autoclean="true" hashModifiedDate="true" subfolders="8192" asyncWrites="true" asyncBufferSize="10485760" cacheAccessTimeout="15000" logging="true" />
Not sure if is something I can achieve using the existing parameters. My goal is to invalidate the cache preferably when the new image has been uploaded without having to change the query string serving the image to get the new one.
I was thinking:
Maybe having a blob storage trigger that when a replacement image has
been uploaded, fires a webhook that deletes the cache for that image?
Or a web request to my imageresizer app to preload the new image in
cache so it replaces the old cached image???
I've seen some posts about using IVirtualFileWithModifiedDate but from what I understand that would have a big performance impact? Is probably 5% of our images request that will have someone uploading an image and expecting it to see it right away since most of the images barely change but it's really frustrating if the image doesn't show the new one not even a day after they have uploaded it!
If I can use IVirtualFileWithModifiedDate to invalidate the cache when the image has changed and not in every image request? Would that be possible?
I get the old image in some browsers/computers and the new one in others.
That different browsers are displaying different versions indicates that either browser caching or proxy/CDN caching is at fault.
ImageResizer's DiskCache hashes the modified date, so it is always as correct as the storage provider.
Regarding your expectations around server-side invalidation:
You're using checkForModifiedFiles="true" cacheMetadata="true", which means that Azure is queried for the latest modified date, but that metadata is cached with a sliding expiration window of 1 hour. I.e, if a URL hasn't been accessed in 1 hour, the next request will cause the modified date to be checked. See StandardMetadataCache.
You can change this behavior by implementing IMetadataCache yourself and assigning that cache to the .MetadataCache member of the storage provider you're using.
Regarding this document, "entry-time-to-live-expiration" means How long the region's entries can remain in the cache without being accessed or updated. The default is no expiration of this type. However, when I use Spring Cache and client-region with following configuration, I find that setting dose not work well with being accessed. Going forward, regarding this document-> XMLTTL tab, it said "Configures a replica region to invalidate entries that have not been modified for 15 seconds.". So I am confused if TTL work for being accessed.
<gfe:client-region id="Customer2" name="Customer2" destroy="false" load-factor="0.5" statistics="true" cache-ref="client-cache">
<gfe:entry-ttl action="DESTROY" timeout="60"/>
<gfe:eviction threshold="5"/>
</gfe:client-region>
So, the documentation you might want refer to is here and here. Perhaps relevant to your situation is...
"Requests for entries that have expired on the consumers will be forwarded to the producer."
Based on your configuration, given you did not set either a ClientRegionShortcut or DataPolicy, your Client Region, "Customer2", defaults to ClientRegionShortcut.LOCAL, which sets a DataPolicy of "NORMAL". DataPolicy.NORMAL states...
"Allows the contents in this cache to differ from other caches. Data that this region is interested in is stored in local memory."
And for the shortcut of "LOCAL"...
"A LOCAL region only has local state and never sends operations to a server. ..."
However, it does not mean the client Region cannot receive data (of interests) from the Server. It simply implies operations are not distributed to the Server. It may be expiring the entry and then repopulating it from the Server (producer).
Of course, I am speculating and have not tested these ideas. You might try setting the Expiration Action to "LOCAL_DESTROY" and/or changing your distribution properties through different ClientRegionShortcuts.
Post back if you are still having problems. I too echo what #hubbardr is asking.
Cheers!
-(void)setImageWithURL:(NSURL *)url,
the method in AFNetworking described: "If the image is cached locally, the image is set immediately", but it does not make me to set cache directory, so where it cache the image in? Or is it really cache the image?
AFNetworking takes advantage of the caching functionality already provided by NSURLCache and any of its subclasses.
Use Pete Steinberger's fork of SDURLCache which provides disk caching, which is not otherwise implemented by NSURLCache on iOS.
Note: as of iOS5, this is no longer needed. NSURLCache now properly caches objects, as long as the Cache-Control header is set.
You may find it useful to set ignoreMemoryOnlyStoragePolicy to YES for the SDURLCache instance, which will ensure that images will be cached to disk more consistently for offline use (which, as reported in the SDURLCache README, iOS 5 supports, but only for http, so it still remains a good option if you want to support iOS 4 or https)
Refer AFNetworking-FAQ - Does AFNetworking have any caching mechanisms built-in? and also AFURLCache - disk cache for iOS links.
I have a CherryPy app that dynamically generates images, and those images are re-used a lot but generated each time. The image is generated from a querystring containing the variables, so the same query string will always return the same image (until I rewrite the generation code) and the images are not user-specific.
It occurred to me that I should be aggressively caching those images, but I have no idea how I would go about doing that. Should I be memoizing in CherryPy? Should I do something like this for Apache? Another layer entirely?
Your first attempt should be to use the HTTP cache that comes with CherryPy. See http://docs.cherrypy.org/dev/refman/lib/caching.html for an overview. From there, it's usually a "simple" matter of balancing computational expense versus RAM consumption via cache timeouts.