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

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.

Related

Mutable object state replication across distributed web sessions

I'm wondering why there is no single notice about the importance of immutability property when storing serializable objects in the HTTP session? I tried to check the JSF and Servlet API specifications but couldn't find anything related.
I've seen a specific problem in the case of JSF based clustered application where #SessionScoped managed bean is mutable i.e. user-modified parameter is stored as a field of this managed bean.
Trouble begins when the node "owning" the session (thanks to stickiness requirement in servlet API specs) dies and different node starts to take over serving the session, the latest state is lost. In fact, only the initial state is replicated. I believe this is because managed beans are placed in session (and replicated to backup nodes) only when they are created for the first time, at least this is confirmed by my tests performed on Websphere.
While one can debate whether this is a good design or not, JSF and even Servlet API still allows it to happen.
I also found some note in Oracle docs:
As a general rule, all session attributes should be treated as immutable objects if possible. This ensures that developers are consciously aware when they change attributes. With mutable objects, modifying attributes often requires two steps: modifying the state of the attribute object, and then manually updating the session with the modified attribute object by calling javax.servlet.http.HttpSession.setAttribute(). This means that your application should always call setAttribute() if the attribute value has been changed, otherwise, the modified attribute value will not replicate to the backup server.
Apart from manually updating the attribute as described above, is there any clean solution, preferably in an idiomatic JSF way?
In WebSphere Liberty, there is a property called
writeContents = "GET_AND_SET_ATTRIBUTES"
for the mutable session objects. For details, please see:
https://github.com/OpenLiberty/open-liberty/issues/2802
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_httpSessionCache.html
Same property apply for database persistence.

Should objects stored in the sessionScope be thread-safe?

If I'm informed correctly, every request for/from a XPage is processed in a new thread in the JVM on the Domino server.
Hence, all objects stored in the applicationScope which might be modified concurrently by different users should be thread-safe. However, all the articles about thread safety I have read so far never say anything about the necessity of using thread-safe objects in the sessionScope.
A user could, for example, run the same XPage (which modifies a sessionScope object) in two different browser tabs at the same time.
In my opinion, that sessionScope object has to be thread-safe too, or did I get something wrong?
In general, whenever there is more than one thread trying to access the same object and at least one of them tries to modify the state of the object it needs to be threadsafe.
So in this case if two browser tabs try to access same xpage or different xpages but trying to access the same session scope object and at least one of them trying to modify that object, we need to ensure it is threadsafe.
As #Tiny commented regarding the view scoped beans, "According to the JSF specification, AJAX requests made from the same view are queued on the client side. Therefore, the possibility of concurrent access in a view scoped bean is zero. A view scoped bean is not shared across different tabs / windows of the same browser".
Refer to Section 13.3.2 of jsf 2.0 specification.

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

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....

Backing bean organization in JSF

I have been thinking about this for a while now and have yet to come up with a best practice for how to organize my beans/classes in a JSF project for the presentation tier. Obviously there are many factors that come into play, but I would like to discuss. Here is my current line of thought:
Consider a basic JSF (still stuck on JSF 1.xx here unfortunately) application that contains a view page (view the data) and an edit page (add, update, delete the data). Here is how I would organize the project:
Request scoped BackingBean:
View related stuff (save status, render logic, etc.). Stuff that is only needed in one request
Actions, action listeners, and value change listeners. If they are applicable to more than one view, they can be separated into their own file.
Session scoped BackingBean:
Anything that needs to remain around longer than one request. Database data, SelectItems, etc.
This bean is injected into the request bean, and stores instances of any data objects
Data Objects:
It doesn't seem to make sense to make the data objects into beans, so they are stored separately. This would be things like User, Book, Car, any object that you are going to display on the page. The object can contain view helper methods as well such as getFormattedName(), etc.
DAO:
A non-bean object that handles all interaction with the business logic tier. It loads the data bean and prepares submits, etc. I usually make this a class of public static methods.
Converters, Validators:
Separate files
This seems to be all that is needed in your average JSF application. I have read through this: http://java.dzone.com/articles/making-distinctions-between, as well the replies here: JSF backing bean structure (best practices), but I never felt like we got a complete picture. BalusC's response was helpful, but didn't seem to quite cover a full app. Let me know your thoughts!
I think you are on the right track generally, however I would do a few things differently:
I would take your DAO layer and split it into two seperate layers, one pure DAO layer that merely is responsible from fetching data from various sources (Eg. database calls, web service calls, file reads, etc...). I would then have a Business Logic layer that contains passthroughs to DAO calls as well as any additional calculations, algorithms, or other general business logic that isn't specific to any one JSF view.
In the MVC pattern, your ManagedBean plays the role of the Controller, and as such should also be the repository for Presentation Logic (logic that is specific to manipulating the view or interacting between various View components). It will also tie your business logic into the event behavior as well.
I would not use public static methods for your Business Logic or DAO layer. This doesn't lend itself well to automated unit tests and prevents your app from utilizing Dependency Injection frameworks like CDI or Spring. Instead create an interface for your BO's and DAO's and then an implementation class for this.
On that note, utilize a Dependency Injection Framework like CDI or Spring :) It will allow you to automatically inject Business Logic objects or DAO's into your ManagedBeans as well as your unit tests. It will also allow for you to swap implementations or DAO's without any coupling to code in other layers of your application.

Why should we make a SessionScoped ManagedBean thread safe in JSF?

I know that Application-Scope persists across multiple users, so it's obvious that we should make sure that all the ApplicationScoped ManagedBeans are thread safe.
I also understand that we don't need to care about thread safety for a RequestScoped ManagedBean. That's because it last only for one HTTP request, and is newly instantiated for each request if it's referenced.
But I am not quite sure why we should worry about thread safety for a SessionScoped ManangedBean. Even though it persists across multiple requests, each individual user gets his/her own instance of it, right?
So, why do we need to worry about thread safety in case of SessionScoped ManagedBeand, and does that apply to ViewScoped ManagedBean too? ViewScope persists across 2 consecutive requests for the same view, right?
If you already worry about the threadsafety of the data in a certain scope, then the data most likely belongs in a more narrow scope (i.e. there is a flaw in the high level design). If the data is been put in the right scope, then there's totally no reason to worry about threadsafety. I assume that your beans are designed the right way that they aren't doing any business logic in the getters.
Use the application scope for application wide data/constants, such as dropdown lists which are the same for everyone. Use the session scope for client specific data, such as the logged-in user and user preferences (language, etc). Use the view scope for rich ajax-enabled dynamic views (ajaxbased validation, rendering, etc). Use the request scope for simple and non-ajax forms/presentations.

Resources