In CherryPy, each request runs in a thread, and that thread has access to a session object via cherrypy.session. If, from that request thread, you launch another thread, thereby allowing the request to return, you no longer have access to that session object. Is there any way around this?
I have a function that runs when the user loads a specific page. Under certain circumstances, this function could take some time (say 10 seconds or so) to run. The results of this function aren't used directly in page rendering, rather they are stored in the users session object for later (instant) retrieval when the user clicks a button. Rather than make the user wait for the data to be compiled, I would like to offload this function to a background thread and let the main thread return the page to the user, but when I do that I no longer have access to the users session object to store the result. How can I work around this? Thanks.
In my specific situation, I am using a custom class for my session (a PostgreSQL session class), but I would think the same procedure would apply regardless. When the initial request comes in, I pull the session_id from the cherrypy.request.cookie object, and pass it to the function that I run in the child thread.
Then, in that function, when I need to access the session object, I instantiate a new session object myself using the session_id, and after setting the desired value call save() on the instance. Works perfectly for me!
Related
Scenario:
We are using azure redis session provider. When page first loads, retrieves the data from external API and stores them in redish session.
The same session data is retrieved via different pages and components with in user session. The question is:
Does application gets the session data only once and stores locally http current context? Or everytime it goes to redis store?
What if we are encrypting the data on set and decrypt the data on Get operations?
Thanks.
Application gets the session-data from Redis everytime you ask for it... for the writing part, you'll have to wait until the dictionary key is unlocked. See https://msdn.microsoft.com/en-us/library/aa479041.aspx#aspnetsessionstate_topic3 assuming you are using asp.net for this
A page claims write access to the session state by setting the EnableSessionState attribute on the #Page directive to true. (This is the default setting.) A page, though, can also have read-only permissions on the session state, for example, when the EnableSessionState attribute is set to ReadOnly. In this case, the module will hold a reader lock on the session until the request for that page finishes. As a result, concurrent readings can occur.
If a page request sets a reader lock, other concurrently processed requests in the same session cannot update the session state but are at least allowed to read. This means that when a session read-only request is being served, awaiting read-only requests are given higher priority than requests needing a full access. If a page request sets a writer lock on the session state, all other pages are blocked, regardless of whether they have to read or write. For example, if two frames attempt to write to Session, one of them has to wait until the other finishes.
StackExchange.Redis is just a wrapper (or a abstraction) for the HttpSessionState Module
I'm trying to store data (most probably an object) so that it is accessible to my entire application. For example, info about my current logged in user (user ID and name).
I am wondering what the most efficient way is to do this in Node and Express?
After doing some research, I found a few ways, although most seemed quite unorthadox such as global objects (global.myuser = {}).
I also found that I could store an object as a module and include it where I need it, although I'm not too sure if data persists using this method.
What would be the best approach for this?
Have a module manage the data for you and then require() in that module anywhere you want access to it. require() is cached so subsequent calls to it get you back the same module every time which works well for shared data without actually using globally accessible variables which and while maintaining proper dependency management (globals are generally evil in node.js because they don't show dependencies at all).
Please be aware that globally accessible data in node.js is shared by requests from all users unless you specifically make it only available to some. So a variable like global.myuser sounds suspiciously dangerous unless the myuser is a server user (something there is only one of), not an actual user from a request.
Here's a simple example:
// shared_data.js
var myData = {someKey: 12345678};
module.exports = myData;
Then, in other modules:
var sharedData = require('./shared_data.js');
// you can access the sharedData object here
If you're trying to remember logged in users, then you need a more involved system that involves keeping track of a given user via a login cookie token and storing valid login tokens on the server that various requests can check to see if the user is actually logged in.
For logged in users with Express, I'd suggestion using express-session as it does 90% of the work for you. You get an object for each logged in user that you can store anything you want in and that info will be directly correlated to only that user.
The session object for the current user will automatically be available in the request object on any incoming request. And, you can pass that session object to any other function you wish to call from within a request.
You cannot use global for saving the current logged-in user. The problem is that all the users, will have the same global. So guest user will have access to admin pages.
If you need to share data between express modules, you can add anthing you want to the request variable.
app.get('*',function(req,res){
req.firstRoute=true
req.currentUser=30
})
app.get('/othertoure',function(req,res){
console.log(req.firstRoute) // = true
console.log(req.currentUser) // = 30
})
Is it possible to get session data from within a Yesod Handler test?
For example I'd like to get the current userId.
Later on, I'd also like to test two simultaneous browser sessions interacting with the Yesod app in turns.
getRequestCookies does return the session, but in an encrypted state.
I have noticed that in order to store a value into the session you simply call
req.session.key = value
without the need to specify a callback. I have set mysql as my session storage adapter using the connect-mysql module. So I am wondering that consider each time I save a value to the session it is being updated in the db, shouldn't there be a callback associated with this? Yet everywhere I look people are happily using it synchronously. Can someone please explain why this is the case? THanks.
The session middleware only actually interacts with the data-store twice per request, rather than immediately with each change:
With Store#get() to retrieve the Session in bulk at the start of a request. (source)
With Store#set() (via Session#save()) to persist the Session in bulk at the end of the request. (source)
Between these steps, changes to the session can be done synchronously. They just should be done before res.end() or similar (res.render(), res.json(), etc.) is called.
I have a requirement where I am planning to run a background process.
Once user logs in into application, I need to have two processes done.
1. authenticate user and go to homepage
2. Get some data and put it in session.
If I do both at same time its going to take 10 minutes to get to homepage. Instead I want second process to run in background while authentication is being processed.
I don't need data from second process in homepage. I need it in some other page which i could access from session.
Can someone put me in right direction?
Thanks
Create a class which extends Thread or implements Runnable and run it. You can learn at the Sun tutorial how to do it. Reference it in a session scoped managed bean so that you can access it from other pages.
That said, it sounds like as if you're hauling some database table entirely into Java's memory which lasts 10 minutes. I strongly recommend to not do so. This is very memory-inefficient and it may blow up whenever multiple users accesses your application concurrently. Add some search/filter/paging logic and just write code accordingly that it queries only the data of interest based on the current request. Google also doesn't query zillions of records to store it in the session and display only 10 of them in the current request. Don't let Java take over the role of the DB and also don't underestimate the powers of the DB. It's very fast when properly modeled and indexed.