Drools design: when to use stateless or stateful - session

In the exploration of finding out when to use stateful or stateless session in Drools, the next information is very useful:
Drools:stateless vs stateful knowledge session
Stateless Vs Stateful Session behavior in drools
drools stateless vs stateful session
It seems clear when to use stateless vs stateful session.
But I became somewhat confused because of the following information here:
http://drools-moved.46999.n3.nabble.com/Use-of-StatelessKnowledgeSession-td2828548.html
In that link people discuss switching from stateful session to stateless session.
Gathering all information, I conclude that it seems possible to switch a stateful session to a stateless session, to avoid possible memory problems (?), by:
Adding facts into a List
Add the List to the stateless session with the execute command (or either add it to a global).
Obtain the different facts in the rules with a query
Add results to a global variable or variables to be able to obtain the results from the stateless session
Which seems like bad practices to me, only to avoid the use of a stateful session.
My questions are:
Is my previous conclusion correct?
Why would I want to switch from stateful sessions to stateless sessions? Is there a memory problem in KIE and when do these occur?
I think the real difference between stateless and stateful sessions comes to the fact whether I just validate (in stateless session) data or add value (in stateful session) to data. That would be a design issue, not a technical issue. Is that correct?

Related

Open Session In View OSIV - Does this happen for every request / thread?

I have turned off the OSIV in a Spring project as I have been reading why it (controversially) may be a bit of an anti-pattern. Not wanting to poke that debate as I have seen it gets heated but I am more interested/lost in the technicals.
Either way, I was wondering exactly when does a session become opened? Is it for ANY web request that comes in or is there some way the application knows that it will only be needing a session for certain endpoints? I am guessing the OSIV Filter is basically always called for every request and a hibernate session to the DB is aquired and added to the webrequest/thread?
I.e. is it OSIV for everything or only certain requests get the session bound through the
entire filter chain and then the controller/services and back out?
When they say "session" I am right in assuming that means it has gotten an active jdbc connection and opened connection to the database...even if I may not use it, and that is where the sort of blocking IO problems could occur say if we are waiting on 3rd party responses although we are now out of a #Transactional service method boundary and we get a spike in traffic?
What exactly is opened session wise? Is a database transaction started via the session "just in case" on every request? Or is there just a hibernate session created for each request and then a transaction is only started if a JPA/Hibernate query is started somewhere along the request (with or without #Transactional).
Any clarification would be excellent!
Vlad Mihalcea - OSIV Anti-Pattern
Baeldung - OSIV
Transactions are only started when you run a method annotated with #Transactional. OSIV just eagerly opens/creates a Hibernate session which can be used for lazy loading through out the whole request lifecycle, but the connection is only acquired lazily i.e. on first database access. Once it is acquired, it depends on certain settings when the connection will be released, but usually it is kept open until the session closes.

Recover session EJB

I was checking EJB stateful beans, the typical example for using this bean is in a shopping cart.
So in the example what is done is check in HttpSession if the EJB exists, if not, one EJB instance is called and then upload to session using the HttpSessionId as identifier.
So, what is the advantage of using a stateful EJB when I could use a simple POJO to do exactly the same?
I guess the typical answer is that even if the HttpSession goes down the EJB still lives in the server container. If this is true, how can I recover that EJB from the EJB pool? given I don't have the HttpSessionID anymore.
Is there another approach to recover EJB's that are living in a container?
The shopping cart of a Stateful EJB hosted within an http session is in my opinion the typical example of something that shouldn't be done for a very simple reason: a shop online purpose is to increase traffic and number of (paying) users. A Stateful bean on the opposite is not recommended with this kind of web site, it doesn't scale.
Stateful Bean are something that should belong to the realm of desktop applications i.e. Swing, JavaFX etc... it has little to do with an www shop online.
Of course keeping things in a session is much lighter than having a Stateful bean holding data.
I cannot think of any trick to recover a Stateful EJB once you loose its reference.
Also, what do you mean with "if the session goes down" ? If you mean because of a server crash, keep in mind that if the EJB resides in the same server then an EJB (Stateless, Stateful, Singleton, etc...) cannot survive a server crash.

Do I need to call setAttribute() for every change if I use Spring Session?

I am in the progress of migrate my spring mvc + hibernate based application to clustered environment (Tomcat clustering). I am researching on the possible solutions for the session replication / sharing. From the Terracotta documentation
All clustered session implementations (including terracotta Sessions)
require a mutated session object be put back into the session after
it's mutated. If the call is missing, then the change isn't known to
the cluster, only to the local node. For example:
Session session = request.getSession();
Map m = session.getAttribute("foo");
m.clear();
session.setAttribute("foo", m); // Without this call, the clear() is not effective across the cluster.
Just want to know if the same rule holds true for Spring Session? I mean the Spring Session Project
Anyone knows the reason behind this rule? Is it because only when that method is called, Spring Session or Terracotta Web Session serialize the attribute object? Without this call, they don't know the object has changed? i.e. they won't monitor the object for changes?
Do you know a clustering solution that don't have this rule?

EJB stateless session beans and stateful session bean

I have gone through various books on stateful and stateless session bean and how they work. I want to know the real usage of these ejbs and advantages over using plain java classes. Basically when do you go for stateless ejbs and when do you go for stateful ejbs. I want a real time application.
the usage of these type of ejbs are usually in service layer as service classes.
EJB3 stateless and stateful bean are actually POJO (with some annotations) and they don't have any big difference with normal classes.
but in term of usage, they have some abilities that you can't find in normal classes like:
they can be called remotely (e.g. RMI protocol).
they can use application server context resources like DB Connection and Transactions.
stateless or stateful:
- if a task or process can be done in a single step (by a single method call) stateless is the right option
like a authentication process
- if a task needs a series of method calls (more than one) and you need to keep previous results to use them in next call, then go for stateful.
like a shipping process (select items, add/remove and then do the transaction)
http session or stateful?
ejbs can be served in application server and they may have different type of clients like a normal swing application or ..., so you can't relay on http session in these cases.
if your appserver and webserver are different (distributed) its not good idea keep data in http session and pass/getback it to/from app server (network overhead).
Stateless session bean are lightweight: they do not store information about a specific user. They are usually used in a static way. For example a client ask for a product information will communicate with a stateless session bean. ("You want the price of product 'YXZ', here you go!")
Stateful session bean however remember's the client information. They contains data about the user actions. For example, let's say a user go through a shopping cart. The steps will be stored in a stateful session bean (for example, user it at the payment step).
You really need both type of session bean in any website. Unless you web site is so basic that anything can be done with stateless session bean (a read-only web site really).
Any web site that track a user through cookies, will need a stateful session bean. Be aware however that you can decide to put very little session information in a session bean and store that information in a database. But you still need some session management.
Developers prefer to maintain state in web layer in modern enterprise applications. I have never seen a real world web application using Stateful Session Bean. It is a scalability issue also.
An example is a shopping cart stateful session bean that tracks a client's product choices and can execute a sale when requested.

How is that instance pooling with EJBs can improve performance?

How is that instance pooling with EJBs can improve performance? Wouldn't you be able to accomplish the same performance just with threads like a java servlet?
Or perhaps instance pooling with EJBs happens for another reason?
Instance pooling not only helps because you can re-use objects (and avoid costly object creation), but also allows the app. server to manage the load correctly. It's app. server specific, but you can normally specify max-pool-size, min-pool-size, pool-resize and the timeout.
When the pool has reached its max-pool-size capacity, requests are served using the existing instances, and will time out if no instance is available within the expected time frame. That may degrade the quality of service of the application, but at least it doesn't blow the app. server itself. That's the same as with a web server.
A few notes about thread-safety:
Sect. 4.3.13 "Serializing Session Bean Methods"
The container serializes calls to each session bean instance. Most containers will support many
instances of a session bean executing concurrently; however, each instance sees only a serialized
sequence of method calls. Therefore, a session bean does not have to be coded as reentrant.
As per the EJB spec, all requests to a specific instance of a bean are synchronized by the app. server. This is, for instance, to allow a stateless session bean (SLSB) to store a database connection in one of its fields. The fields of an SLSB should be transient, though. (The bean instance can be destroyed/re-created any time.) With the synchronization, the app. server ensures the SLSB is thread-safe. Without the synchronization by the app. server, the developer should ensure that the SLSB is thread-safe, that is, it should have no fields.
Note: It's rare to have fields in an SLSB. Most SLSB are thread-safe by nature. I would not recommend storing the connection in field for instance. Better obtain one in the method, and release it in the method asap.
I think instance pooling is used when the beans are expensive to construct. By letting the next request reuse the same bean you don't have to construct another instance.
If the bean itself is cheap to construct and the cost is in the work that it's doing, then instance pooling isn't worth the hassle.
I think the advantages would be similar to those of connection pooling. Having instances ready in a pool avoids the overhead of creating a new instance every time the EJB is requested.
Another advantage, depending on how you look at it, is that by using a maximum pool size you can limit the damage a runaway application can do by forcing it to wait for an instance to become available. This can help prevent poorly written apps from monopolizing server resources.
AFAIK the fundamental reason is the different threading model compared to the servlet's one. In case of servlet, there is only one instance and many threads can operate on this intstance at the same time. It is the developers responsibility to ensure proper synchronisation.
In contrast to this, ejb container allows only one thread at the same time to operate on the bean instance (including necessary synchronisation at the background). Thanks to this, developer does not have to care about synchronisation, and what's more using synchronisation in the bean's code is forbidden by the spec (in fact you can do it, but you have to consider the performance consequences).
So to enable concurrent processing, you need to pool multiple bean instances so that multiple threads can access them simultaneously. The size of the pool can be tuned depending on what kind of work is done inside the bean. The basic rule is:if the task is I/O bound, you need big pool so that the cpu time is not wasted when waiting for i/o response. If the task is cpu bound, the pool should be as big as much processors/cores the machine does have. But the tuning should be based on measuring.
One more note on the servlets: you can enforce the same behaviour as ejb when using SingleThreadModel interface. But in fact this is not much used I guess.

Resources