My app's webView loads a page and I inject some javascript which automates a click for me and adds an item to my wish list. For something like this would you recommend using a data session or an ephemeral session to load the page? Speed is important to me, and I'm trying to optimize is as much as I can in Objective-C (yupp, even milliseconds).
The page basically loads a product page so everything but the actual product is always going to be the same (background view, website menu bar, button images, etc). Right now I'm using NSURLConnection, and I'm trying to update my code to use NSURLSession instead.
Default sessions behave similarly to other Foundation methods for downloading URLs. They use a persistent disk-based cache and store credentials in the user’s keychain.
Configuration that uses global or shared cookie, cache and credential storage objects. Behaviour is similar to NSURLConnection.
The shared session uses the global singleton credential, cache and cookie storage objects. This can be used in place of existing code that uses +[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]
Ephemeral sessions do not store any data to disk; all caches, credential stores, and so on are kept in RAM and tied to the session. Thus, when your app invalidates the session, they are purged automatically.
Private Session Configuration that does not persist cookie, cache and credential storage objects. As the name indicates, the configuration settings are short living and are deleted when the session is invalidated.
Background sessions are similar to default sessions, except that a separate process handles all data transfers. Background sessions have some additional limitations, described in “Background Transfer Considerations.”
Background session is similar to Default session, But it can be used to perform networking operations on behalf of a suspended application, within certain constraints.
Similar to default session but upload or download of data can be performed even when the application is in suspended state.
Reference from Apple Doc
//Default session
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
//Ephemeral
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
//Background
+ (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier;
NSURLSession Tasks and Delegates
Below image explains types of NSURLSession Tasks and their hierarchy.
More Details
I think you'd use a default session as you want it to cache data to disk. Something an ephemeral session doesn't
The bottleneck is almost always IO so you want caching when the data doesn't change anyways.
For rapidly chaining data this wouldn't be worth it but you explicitly say that the data won't change
Related
I don't understand the idea of TIdHTTPSession in TIdHTTPServer. What is it for? Is it a kind of container for request, or what is it? How do I use it properly after I have enabled AutoSessionStart? And what will happen if I do not enable AutoSessions?
For example, say we have some shared resourse FMyMessages: TStringList; Then how should I request this shared resource with/without sessions?
TIdHTTPSession has an FLock: TIdCriticalSection; member - so maybe I should use it to lock my shared resource FMyMessages from other threads if I have AutoSessions, otherwise I should use my own critical section?
Also, how can I count Sessions in the moment? I tried like this but it doesn't work:
Server.Contexts.Count.ToString;
I don't understand the idea of TIdHTTPSession in TIdHTTPServer ? What is it for? Is it a kind of container for request, or what is it? How do I use it properly after I have enabled AutoSessionStart?
HTTP is a stateless protocol. It does not remember information from one request to the next. And it does not even guarantee or require that the TCP connection itself remain open between requests.
That is where sessions come into play. The server can create a session object to store information, such as during a client login, and that session's unique ID is sent to the client via an HTTP cookie, which the client can send back to the server on subsequent requests to reuse the same session object. Eventually, the session will timeout and be destroyed, if you do not end the session explicitly, such as during client logout.
And what will happen if I do not enable AutoSessions?
The server will simply not automatically create a new session object if one does not exist yet for each request. You would have to create a new session manually on an as-needed basis instead.
For example, say we have some shared resourse FMyMessages: TStringList; Then how should I request this shared resource with/without sessions?
Sessions have nothing to do with accessing shared resources, and everything to do with persisting per-client state data. Such as user logins, database connections, etc.
TIdHTTPSession has an FLock: TIdCriticalSection; member - so maybe I should use it to lock my shared resource FMyMessages from other threads if I have AutoSessions, otherwise I should use my own critical section?
No. You can use Indy's TIdThreadSafeStringList instead.
Also, how can I count Sessions in the moment? I tried like this but it doesn't work:
Server.Contexts.Count.ToString;
The Contexts property stores the active client TCP connections. That has nothing to do with HTTP sessions. Those are stored in the server's SessionList property instead.
I've just come across something that has entirely changed my mental image of URLSession caching in iOS.
We were hitting an endpoint that only ever got hit once.
Restarting the app wouldn't hit the endpoint again.
Deleting the app would cause it to hit the endpoint again... but only once.
The header of the response contains...
Cache-Control public, max-age=1800
So it is down to caching. By manually telling the URLSession to ignore the cache it would hit the endpoint again.
In the docs it shows the caching policy and how it works as a workflow diagram.
https://developer.apple.com/documentation/foundation/nsurlrequestcachepolicy/nsurlrequestuseprotocolcachepolicy
But where is the cached data stored once the app is terminated? Surely the app and everything to do with it is removed from memory?
The URLSession is using URLCache for it's caching system. It's used for all network resources. You can access it directly or setting your own through URLSessionConfiguration. The underlying location of the URLCache is on the file system rather than in memory. There is a way to manage cache yourself though. Say, for instance, your response should be encrypted on the device. Slightly bad example, but you get the point. ;)
Here's an article how to manage cache programmatically if you are needing more control over caching.
I've built a Progressive Web App that uses caching, but it's unclear to me whether users can (accidentally or on purpose) clear the service worker cache, which may clear my tracking data.
When a user clears their browsing data / cookies, this clears all site storage which includes the SW cache, cookies, local storage, indexeddb, and any other local caching system.
Furthermore, Ctrl-F5 forces a cache refresh, and is intended to abandon all cached content including service worker cache and just retrieve all content from the servers again.
"Clear site data" in Chrome 76 will delete the caches and the worker, however the deleted worker remains "activated and running". So that's a case that needs dealing with.
Is it possible to change the value for allowsCellularAccess on an existing NSURLSession by modifying the underlying NSURLSessionConfiguration?
I want to honor any changes in a user's settings for my application without cancelling existing requests if their device is currently connected to WiFi.
No. A session copies its configuration. It does not retain it. What I would do in your situation is:
Make a copy of the session's existing configuration and change that flag.
Create a new session with the modified configuration.
If the user is on Wi-Fi, call finishTasksAndInvalidate on the old session. This will keep the session around long enough to finish any existing requests, after which it will go away.
If the user is on cellular, call invalidateAndCancel, then wait to restart those tasks until the user is on Wi-Fi.
Additionally, you may be able to call cancelByProducingResumeData: on a task, and then recreate (resume) it in a different session with a different configuration. The task will still report its original configuration for allowsCellularAccess, but will behave according to the configuration of the new session. (The stale reporting might be considered a bug.)
What will be the most efficient way to make an ASP.NET MVC application web-farm ready.
Most importantly sharing the current user's information (Context) and (not so important) cached objects such as look-up items (States, Street Types, counties etc.).
I have heard of/read MemCache but haven't seen a simple applicable way (documentation) on how to implement and test it.
Request context
Any request that hits a web farm gets served by an available IIS server. Context gets created there and the whole request gets served by the same server. So context shouldn't be a problem. A request is a stateless execution pipeline so it doesn't need to share data with other servers in any way shape or form. It will be served from the beginning to the end by the same machine.
User information is read from a cookie and processed by the server that serves the request. It depends then if you cache complete user object somewhere.
Session
If you use TempData dictionary you should be aware that it's stored inside Session dictionary. In a server farm that means you should use other means than InProc sessions, because they're not shared between IIS servers across the farm. You should configure other session managers that either use a DB or others (State server etc.).
Cache
When it comes to cache it's a different story. To make it as efficient as possible cache should as well be served. By default it's not. But looking at cache it barely means that when there's no cache it should be read and stored in cache. So if a particular server farm server doesn't have some cache object it would create it. In time all of them would cache some shared publicly used data.
Or... You could use libraries like memcached (as you mentioned it) and take advantage of shared cache. There are several examples on the net how to use it.
But these solutions all bring additional overhead of several things (like network and third process processing and data fetching etc.) if nothing else. So default cache is the fastest and if you explicitly need shared cache then decide for one. Don't share cache unless really necessary.