XPages: what is the lifetime of an application scope variable? - xpages

A. What is the actual lifetime of an application scope variable in xpages?
B. how can i remove/reset it if necessary?
(I can't find anything like "re-deploy" or "start-stop application", so do i have to restart the webserver,do it with code, just re-save my application from designer or anything else...?)

A. It varies. You can set an explicit timeout in the XSP Properties (surfaced in Designer 9 as a design element under the Application Configuration category; in 8.5.x you'll need to navigate to WebContent/WEB-INF/xsp.properties via Package Explorer). Otherwise, it times out when Domino thinks it "should". This is based on application usage, so the more heavily the app is used, the less likely the scope will ever expire unless the HTTP task -- or Domino itself -- is restarted.
B. To destroy the entire scope, restart HTTP (or restart Domino entirely). NOTE: this is not
Tell HTTP Restart
...which only reloads certain portions of the task, and does not reload the JVM. You need to actually restart the task:
Tell HTTP Quit
Load HTTP
OR
Restart Task HTTP
After the task restarts, a fresh application scope will be instantiated the next time the application is accessed.
You can also selectively clean the scope. Each of the scopes in XPages (request / view / session / application) is an instance of a Java Map, so each supports all of the methods defined in that interface.
I would recommend only removing specific items, e.g.:
applicationScope.remove("myBean");
If you clear the entire scope without actually destroying the scope itself (see above), it can cause unpredictable behavior, because the platform also stores its own information in the application scope (this applies to the other scopes as well). You should only remove scope entries that you added.

As the Name application scope variable already tells you its lifetime is as long as the application is running if defined in the xsp.properties if you defined nothing the standard duration is 30 minutes. or Or from IBM:
The applicationScope duration is the WebModule duration. A web module is started when the first request comes in, and is eventually discarded after a period of inactivity, the default being 30 minutes. Every user of the application can access these variables once they are created, so there is no privacy with these variables. The applicationScope should only be used for data that must be shared among many XPages.
If you develope using application scope vars you can reset them by clearing your Application in designer go to: Projekt => clear...
or if this does not help try following code from Tommy Valand:
function clearMap( map:Map ){
// Get iterator for the keys
var iterator = map.keySet().iterator();
// Remove all items
while( iterator.hasNext() ){
map.remove( iterator.next() );
}
}
This will allow you to reset the application scope durring runtime, verry usefull for debugging and testing.

I believe that refreshing the design also clears application scope variables....

Related

How to add global variable in REDIS cache

Need to add global variable in REDIS Cache.
For Ex:
Consider an student, employee and Staff related application.
Every role has a unique object. When student log in to the application we need to get student information from redis. Same for other roles log in too.
If we store all the details at time of application initialization, we no need to send request to get role related details. If we store it into session, that data will be checking by every users login. And also session id has been varied for every users.
Is it possible?
If yes, How can we store the values at the time of application initialization?
First of all, since Redis is a cache, you are storing objects that may be evicted with time. When Redis becomes full, it will start clearing objects according to your eviction policy configuration.
Probably caching everything upon initialization is not the best course of action, I'd go with caching the objects when they are first requested, if they don't exist on Redis, store them for future retrievals. This way, if your Redis instance clears that object, your application logic will always find it (from cache or from local storage). That's called a Cache-Aside Pattern.
Your initialization logic varies depending on which technology / platform are you using.
ASP.NET MVC 5 or lower has the Global.asax file, ASP.NET 5 MVC6 has the Startup.cs file.

Uses of javax.faces.PROJECT_STAGE

I wanted to understand impact of 'javax.faces.PROJECT_STAGE' property for a JSF application. A nice use case was presented in below links
https://dzone.com/articles/jsf-20-new-feature-preview-ser
http://www.java-tutorial.ch/java-server-faces/jsf-project-stage
Except presenting validation error messages, is there any other use case where this property really helps? I understand that we can check this variable to identify the environment and change certain functionality, however is there anything else that JSF does automatically to help developers? Would be great if you can share the experiences from your project?
Setting this param to Development enables better error messages, including in the client-side JavaScript, at the cost of some performance.
While setting this param to Production will turn off some error messages, and emphasize performance.
Source:
JSF 2.0 Reminder: Project Stage
According to the comment by wutzebaer for this linked post the javax.faces.PROJECT_STAGE property may control whether or not certain features are enabled (such as resource caching).
When we setting the PROJECT_STAGE as production we will get better error message, for example when we missed h:form tag around input fields then we may get following error message when stage is set as Development and when the stage is set as Production (or any value other than Development) we won't get any error message.
The form component needs to have a UIForm in its ancestry. Suggestion:
enclose the necessary components within <h:form>
Cache Busting for Resources during development
By resources, I refer to static resources such as stylesheets, javascript libraries, logo's and pictograms, etc.
By default, resources are loaded without any cache expiration (expires at max age or something). This is so, because resources are assumed to be static, in that they do not change during the lifespan of the Servlet Container. We benefit that way from caching those resources on the Client Side (Web Browser caching).
However, when releasing a new version of a library that might wrap a group of resources, we do not want users to get stuck with the old version of a resource. Typically Implementations, and as per the spec, resources will get automatically suffixed with the library name and version as query attributes. A typical resource will automatically be output as something like:
<link type="text/css" rel="stylesheet" href="/nqp-web/javax.faces.resource/components.css.xhtml?ln=primefaces&v=6.2">
This is handled by using a specific implementation of Resource.
So as you release new versions of a library, your users wont get stuck with old versions of resources in their cache.
However during development work, the version does not increase, but you still want the cache to expire, preferably immediately.
The default implementation is usually to make sure that based on the value of javax.faces.PROJECT_STAGE, specifically being DEVELOPMENT, the expire is set to immediate. You can see that in Mojarra's ResourceImpl for example:
long expiresTime;
if (FacesContext.getCurrentInstance().isProjectStage(Development)) {
expiresTime = new Date().getTime();
} else {
expiresTime = new Date().getTime() + maxAge;
}
Logging
As #vrcca already mentioned, a quick search for usages of isProjectStage reveals that this mostly just turns on additional logging when set to DEVELOPMENT.
References
What is the JSF resource library for and how should it be used?
Mojarra Implementation: ResourceImpl
Custom Resource Handler
Another function of setting the PROJECT_STAGE as Development is that we will also be able to see our changes in .xhtml files without restarting the server.

What does it mean by $scope=global in ATG..?

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.

How secure is using the applicationScope in an anonymous XPages application?

In a XPages application, I want to store some (confidental) information in the applicationScope to make it accessible for all users. However, the ACL of the application is configured such that anonymous users are allowed to read public documents. Still, I do not want them to have access to the applicationScope. Is it possible for an anonymous user to access/read the applicationScope?
All the scope variables (including applicationScope) are memory contexts. The term "scope", in this case, refers to how broadly each can be accessed.
requestScope can be accessed by any code executing within the current page for the duration of a single HTTP request, at which point the object is destroyed. Any other pages, and any subsequent requests against the same page instance, have their own separate requestScope.
viewScope can be accessed by any code executing within the current page for the life of that page instance. Other pages -- including those accessed by the same user -- have their own viewScope. Similarly, if the user navigates to another page, and then navigates back to the previous page, that's a new viewScope because it's a new instance of the page.
sessionScope can be accessed by any code executing within any page during a single HTTP session. This is tied to session cookies in the browser, not to authentication. So if an anonymous user later logs in, it's still the same sessionScope. If they later log out, they still have the same sessionScope until they close their browser or the application clears out the storage.
applicationScope can be accessed by any code executing within any page within the current application. This is what allows it to be shared across users: If User1 is accessing app1.nsf/page1.xsp on one computer while User2 is accessing the same page -- or a different page -- within the same NSF, they have the same applicationScope -- the variable refers to precisely the same in-memory object for both users -- so any data stored via code executed by one user can be retrieved via code executed by another user until the application clears out the storage.
BUT, if User1 is accessing any page in app1.nsf and User2 (or Anonymous) is accessing any page in app2.nsf, the variable applicationScope refers to different in-memory objects for each user, because they are accessing different applications, even if there is code in either app that accesses on-disk data in the other app. The in-memory object that the applicationScope variable refers to is different in each NSF, no matter where any on-disk data it may access or create happens to be stored.
So you (and anyone else writing code in the same NSF) still need to be diligent about how you structure your logic to avoid storing sensitive information in applicationScope and then exposing it to users who shouldn't have access to it, but you don't need to worry about code executed from other applications accessing the same memory scope. Code can only read the data you store in your applicationScope if that code is executed from the same NSF.
A user can only read values from applicationScope and other scoped variables if you expose the value through visible controls on an XPage. So if you do not expose the values, then a user (anonymous or not) can not see the value.

XPages cluster and state variables

We are about to make another server for XPages applications. In front of it there will be fail over/load balance component (Microsoft Forefront, IBM Web server) that will redirect HTTP request to one of two cluster servers.
I suppose that scoped variables will be reinitialized in case of fail over - user is redirected to other server which will initialize XPage from scratch (GET) or subset of data (POST). Anything binded to beans/scoped variables will be lost (pager state, application specific data). This can cause odd behaviour to users: loss of entered data or opening of unexpected page. I am aware of fact, that this is highly depending on application design.
The situation can be very similar to expired session on one server - how to prevent loss of data in such case.
Are there any coding best practices how to avoid side effects of fail over from server to server?
While not a code best code best practise, you first need to configure your load balancer to keep users on the same session once started (probably_ using a cookie, so failover only happens when your box really goes down.
Secondly don't take scope variables to be there, always test for them - which is a good practice anyway since a session can timeout and loose its variables on a single server too.
POST will fail due to a lack of x-session, so you might resort to posting only via Ajax that can have an error handler.
You could consider to use cookies to capture state information.

Resources