In Play Framework, if your code runs within Future, it jumps from one thread to another. I have a config object which is instantiated per request, and need to be stored in the Threadlocal. However when the Future is involved, Threadlocal values aren't consistent anymore. How do we try to make the Threadlocal consistent throughout the life of request even if it is jumping between different threads?
Thanks
You can use HttpExecutionContext. Please refer https://www.playframework.com/documentation/2.5.x/ThreadPools#java-thread-locals.
Related
I am looking at developing a solution with Dialogflow, where the User Interface events (e.g. Typed user input) are going to arrive as http REST events.
The problem with this is that the Dialogflow Client API (Note: This is NOT THE SAME THING as the fulfilment API), looks like it is stateful: https://github.com/googleapis/nodejs-dialogflow
(... But I could be wrong on that...)
And stateful is hard in most (all?) modern serverless paradigms that any sane person is probably using. Mainly - There is no gaurantee that subsequent events will arrive at the same run-time instance.
It's a bit infuriating that although many examples are supplied at the repo above, none of them look like realistic (but small) applications, handling multi-session, multi-turn (even 2-3 turns) user input.
Is the idea that any run-time instance could/would call new dialogflow.SessionsClient(); just once PER RUNTIME initialisation (NOT per session) to initialise the API, and then everything else is done via like await sessionClient.detectIntent(request); ???
Now that I've typed this, I am pretty confident that is right. But if anyone could confirm it would be great!
The underlying Dialogflow Session API itself is stateless - any statefull decisions that are made must be included in your call to detectIntent. The JavaScript library reflects this stateless scenario as well.
The SessionsClient constructor sets up the connection and authentication information, but does not maintain any other conversational state. So you can use the same object to manage multiple conversations.
Note that this still means you need to maintain conversational state (the session id, the values and lifespans returned in contexts, etc) in order to pass it to detectIntent as part of the request.
We are struggling now with NodeJS, as we don't want to pass some general request based data through lots of callbacks. We have multiple async calls, changed, updates in one remote method and we need to be able to extract the sessionId and customerId on every step without passing them as parameters to every function. Here is what we tried:
Writing to the "app" object is not secure and is overridden by multiple simultaneous request.
Writing to the "ctx.req" object doesn't change anything, as then you need to pass the "req" object to all callbacks.
Is there a good way to work with kind of request based context, that you can use everywhere in the application or you still need to pass some variable everywhere?
Node.js is best for implementing stateless servers. I don't know your codebase and architecture. But I guess you need to use a persistence store like
Redis or Memcached or Firebase(service)
with a token for each session. And use this token to grab the objects from persistence store. This is a pretty standard approach while implementing stateless servers. Firebase provides the added advantage of realtime updates and even completely bypassing the server if required.
You may have to show some code and design for a more improved answer.
You can use the javascript merit like Ex:
var topFunction={
firstFunction:function(){
console.log(id);
------//work you want to do
},
secondFunction:function(){
console.log(id);
---//work you want to do
}
}
function test(){
var arr=[2,3,4,5,6,7];
topFunction.id=10;
async.map(arr,topFunction.firstFunction.bind(topFunction),function(err,result){
})
You got every time the same id in async call it is best way to use the the async call .You do't need to send the the id again and again .You can use this feature of javascript as context in request.The value of id different for every req
I developing a stateless REST API that makes use of token based authentication, where I'm manually adding an Authentication object to the security context by calling SecurityContextHolder.getContext().setAuthentication(authentication) from within a custom security filter. I've been experiencing problems with the context not being set correctly which I believe is due to this :
Storing the SecurityContext between requests
In an application which receives concurrent requests in a single session, the same SecurityContext instance will be shared between threads. Even though a ThreadLocal is being used, it is the same instance that is retrieved from the HttpSession for each thread. This has implications if you wish to temporarily change the context under which a thread is running. If you just use SecurityContextHolder.getContext(), and call setAuthentication(anAuthentication) on the returned context object, then the Authentication object will change in all concurrent threads which share the same SecurityContext instance. ...
You can customize the behaviour of SecurityContextPersistenceFilter to create a completely new SecurityContext for each request, preventing changes in one thread from affecting another.
So the question is - how do you change the behaviour of the SecurityContextPersistenceFilter?
I'd like the security context to not be associated with the http session, but don't want to set the session creation policy to stateless, because I still want to implement CSRF protection etc.
I had this exact question this afternoon, and this open question matched my search exactly, so I thought I would add the little I learned.
We had threads that were accessing the same SecurityContext. I was unable to figure out how to customize the behavior of the SecurityContextPersistenceFilter directly (and in the pattern of the framework), however there were two ways that I could get it to be thread safe.
The first solution was to ensure that an empty context was created in our main authentication filter. This covered all of our authenticated requests, so it would work for our solution.
SecurityContextHolder.createEmptyContext();
The second thing that worked for me was to change our WebSecurityConfig to be stateless, which I know doesn't work for the OP, but added here for completeness.
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
Both these solutions work independently for our particular configuration. I'm certain there is a 3rd solution that would read better, but I don't know what it is but would like to.
This is my first time posting. I welcome any feedback.
According to the documentation,
Global: Component is shared among all users.
Session: Separate instances of the component are provided to each user.
Is that means, for global component, there is only one instance for the whole nucleus system..
If this is true, how does it valid for components like ‘/atg/dynamo/transaction/TransactionManager’ and most of the droplets..?
Because those components are used by several users at a single moment
Edited:
I understood the ‘TransactionManager’ behavior. According to the definition there should be single transaction manager, and he should keep transaction objects per each transaction.
But my question is still valid for droplets like, foreach, switch, etc (most of them are globally scoped)
If there is only one instance of corresponding class for the whole nucleus system, isn't it having bad effects on performance?
Historically there were three different types of scope available in ATG. This has now increased to 5, with the addition of Window (generally only used in the CSC application so try not to use it) and Prototype (added to support the use of Endeca Cartridge Handlers).
As you highlight from the documentation, global component is instantiated once and is shared by all users, while a session component is created once for a given session and is shared by all requests of that session. Similarly a request scoped component is freshly instantiated for each request that uses it.
From a performance point of view, resolving the path to an existing component (for example a globally scoped component like ForEach) takes a little time, but instantiating a new object (in other words a request scoped component) is comparatively more expensive.
So in the case of a ForEach droplet it gets instantiated once but in the service method it actually extracts the parameters from the request:
String elementName = pRequest.getParameter(ELEMENT_NAME);
This means that your globally scoped component is thread safe in that it only takes in parameter from the current request. So in general, if a component can be shared by multiple users, without worrying about synchronisation, it should be globally scoped versus session or request scoped. (The rule of thumb should be that if your droplet is request scoped, you are likely doing it wrong).
If you are aware of Design Patterns, $scope=global is the equivalent of making an ATG component a singleton.
ATG Commerce has 4 different scopes of components
Global: This is the default scope of the component, if scope isn’t defined.
These components will be initialized once and will be there as a
global object. It’s a best practice to have all the Droplets, Tools,
Manager and other Configuration components as global
Session: The scope and the values maintained will be unique for every
session. The session scope components generally used are ShoppingCart
(Order), Profile, SearchFormHandler etc..
Request:The scope and the values maintained will be unique for every request. The request scope components generally used are FormHandlers to process individual requests.
Window: The scope and the values maintained will be unique till
the browser window is closed. The Window scope components
generally used in CSC application for ShoppingCart component etc..
It’s good to use components with any scope based on business
requirement but having it declared as Global and using it will be a
benificial for improving the performance of the application.
It’s a thumb rule have the business logic in Global scope components and refer it from lower scoped components if required.
This will reduce the threads waiting to be Garbage collected.
Ive some questions about Spring Security 3.0.5 and the SecurityContext. First of all, Ill try to conclude what I know:
SecurityContextHolder stores SecurityContext
Between Request, SecurityContext is stored in HttpSession
Begin of Request: SecurityContextHolder gets SecurityContext from HttpSession
End of Request: SecurityContextHolder puts SecurityContext in HttpSession
During the Request, on the server, SecurityContextHolder uses a ThreadLocal. Everywhere in the application (same request), the SecurityContext can be accessed
Now my question....
--> Two Requests: the SecurityContext-instance will be shared
How does this work? I mean, SecurityContextHolder uses a ThreadLocal for Each Request.
2 Request = 2 ThreadLocals
Each request does: getSessionAttribute (SecurityContext) from HttpSession
What happens if they work on the SecurityContext? Is the SecurityContext changed in all ThreadLocals?
As far as I know: yes (??)
How does this work? How can they work on the same instance? I mean, I really cant imagine how two different threads with two different ThreadLocals can work on the same instance?
API (ThreadLocal):
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable.
I mean, thats it: copy! maybe Im wrong and its not possible for two threads to work on the same SecurityContext? But Spring Security Documentation says so!
Would be great if someone could explain that to me :-) Thank you!
Each thread has its own value of ThreadLocal, but nothing prevents these values from being equal. So, in this case multiple thread would have references to the same instance of SecurityContext.
Usually it's not a problem, but if you want to modify security context, you can enable defensive copying, see SEC-356.