Track actions of several users in a singleton bean - java

I found several resources to help me with this issue, but I can't seem to mix all the ingredients in order to suit my needs.
I want to "lock" a Cat (or even several) from being petted by other users, if a petting of it (or them) is already in progress. I also want to provide a feedback to the caller, telling him who called the API before him.
#Local
#Singleton // or #Stateful?
public class CatPetterBean_Local implements CatBean_Facade
{
/**
* Key - The ID of the Cat
*/
final private ConcurrentHashMap<Integer, User> pettingState = new ConcurrentHashMap<>();
#TransactionAttribute(TransactionAttributeType.REQUIRED)
#Override
public GzipROWithMsg<Object> pet(final ImmutableSet<Integer> catIds)
{
checkIfTheyAreBeingPetted_AndThrowRuntimeExec(catIds);
<...>
// After petting, they will be saved by the caller bean (e.g. CatPetterBeanImpl)
}
<...>
}
Petting takes a while
Cats retain a state in the DB: ALREADY_PETTED and NOT_PETTED. Once it is already pat, it cannot be petted again. I even thought of loading the Cat from the DB and checking its state on-the-fly, but I think it's more network traffic that way.
How can I take advantage of notions like synchronized keywords, #Lock annotations
No, I am not using Spring
No, This isn't a webapp
Yes, I do lack EE knowledge. I'm asking this question in a process of fast learning.

EJB Singletons have under the hood a locking mechanism, by default, all bean methods are serialized via write locks.
The default concurrency model on EJB Singletons is: #ConcurrencyManagement(ConcurrencyManagementType.CONTAINER), this is the default, no need to annotate the singleton with this. When Container Concurrency Management is in play as I said before every method is write locked. If you want finer control over singleton methods you can annotate them with #Lock(LockType.READ) which means that the method can be accessed concurrently while no one holds a write lock on the bean, or #Lock(LockType.WRITE) giving exclusive access to the current thread.
Alternatively, you can use Bean concurrency management. In this case, you should annotate your singleton class with: #ConcurrencyManagement(ConcurrencyManagementType.BEAN).
In this case, you use synchronized and other Java concurrency goodies. For most of my needs Container Managed concurrency was more than enough.
Another remark to the above code fragment is that #Local doesn't seem appropriate, my guess is that CatBean_Facade should be annotated with #Local.

Related

Spring #Cacheable : need to know value return from cache or not

Our applications using Spring Cache and need to know if response was returned from cache OR it was actually calculated. We are looking to add a flag in result HashMap that will indicate it. However whatever is returned by method, it is cached so not sure if we can do it in calculate method implementation.
Is there any way to know if calculate method was executed OR return value coming from cache when calling calculate method?
Code we are using for calculate method -
#Cacheable(
cacheNames = "request",
key = "#cacheMapKey",
unless = "#result['ErrorMessage'] != null")
public Map<String, Object> calculate(Map<String, Object> cacheMapKey, Map<String, Object> message) {
//method implementation
return result;
}
With a little extra work, it is rather simple to add a bit of state to your #Cacheable component service methods.
I use this technique when I am answering SO questions like this to show that the value came from the cache vs. the service method by actually computing the value. For example.
You will notice this #Cacheable, #Service class extends an abstract base class (CacheableService) to help manage the "cacheable" state. That way, multiple #Cacheable, #Service classes can utilize this functionality if need be.
The CacheableService class contains methods to query the state of the cache operation, like isCacheMiss() and isCacheHit(). Inside the #Cacheable methods, when invoked due to a "cache miss", is where you would set this bit, by calling setCacheMiss(). Again, the setCacheMiss() method is called like so, inside your #Cacheable service method.
However, a few words of caution!
First, while the abstract CacheableService class manages the state of the cacheMiss bit with a Thread-safe class (i.e. AtomicBoolean), the CacheableService class itself is not Thread-safe when used in a highly concurrent environment when you have multiple #Cacheable service methods setting the cacheMiss bit.
That is, if you have a component class with multiple #Cacheable service methods all setting the cacheMiss bit using setCacheMiss() in a multi-Threaded environment (which is especially true in a Web application) then it is possible to read stale state of cacheMiss when querying the bit. Meaning, the cacheMiss bit could be true or false depending on the state of the cache, the operation called and the interleaving of Threads. Therefore, more work is needed in this case, so be careful if you are relying on the state of the cacheMiss bit for critical decisions.
Second, this approach, using an abstract CacheableService class, does not work for Spring Data (CRUD) Repositories based on an interface. As others have mentioned in the comments, you could encapsulate this caching logic in an AOP Advice and intercept the appropriate calls, in this case. Personally, I prefer that caching, security, transactions, etc, all be managed in the Service layer of the application rather than the Data Access layer.
Finally, there are undoubtedly other limitations you might run into, as the example code I have provided above was never meant for production, only demonstration purposes. I leave it to you as an exercise to figure out how to mold these bits for your needs.

Single class file on server memory using Spring causing problems

I don't quite know how to explain the situation, I will try to be as clear as possible.
I am currently writing a web-application, using Spring to manage the beans. Obviously, more than one people will use this application. Each user has a set of data related to himself. My problem comes with some poor design I introduced when I just entered the development field. Here is the case:
#Component
public class ServiceClass implements IService {
#Autowired
private Dependency firstDependency;
#Autowired
private UsefulObject secondDependency;
private DataSet dataSet; // THIS LINE IS IMPORTANT
public void entryPoint(String arg1, int arg2, Structure arg3) {
/* Query data from a database specific from the project (not SQL
oriented. I absolutely need this information to keep going. */
dataSet = gatherDataSet(String ar1);
/* Treat the data */
subMethodOne(arg1);
subMethodTwo(arg2);
subMethodThree(arg3);
}
private subMethodOne(String arg1) {
// Do some things with arg1, whatever
subSubMethod(arg1);
}
private subSubMethod(String arg1) {
/* Use the DataSet previously gathered */
dataSet.whateverDoing();
}
... // Functions calling sub-methods, using the DataSet;
As every user would have a different dataSet, I thought it would be good to call it at the beginning of every call to my service. In the same way, as is it used very deep in the call hierarchy, I thought it would be a good idea to store it as an attribute.
The problem I encounter is that, when two users are going through this service nearly simultaneously, I have a cross-data issue. The following happens:
First user comes in, calls gatherDataSet.
Second user comes in, calls gatherDataSet. First user is still treating !
First user still uses the dataSet object, which was overrid by Second user.
Basically, the data first user makes use of become false, because he uses data from the second user, which came in short after him.
My questions are the following:
Are there design pattern / methods to avoid this kind of behavior ?
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
Bonus: (Kind of unrelated) How to implement a very large data mapper ?
Object member variables (fields) are stored on the heap along with the object. Therefore, if two threads call a method on the same object instance and this method updates object member variables, the method is not thread safe.
However, If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.
With this in mind, change your design. https://books.google.co.in/books?isbn=0132702258 is a must read book for coming up with good java based software design
More stackoverflow links: Why are local variables thread safe in Java , Instance methods and thread-safety of instance variables
Spring promotes singleton pattern and (it is the default bean scope). Spring configuration for having two service class objects for two different users is called prototype bean scoping, but should be avoided as far as possible.
Consider the usage of in-memory Map or an external no-sql datastore or an external relational database
Can you configure Spring so that he uses two instances fo two users (and so on), to avoid this kinf od problems ?
You already mentioned correctly, that the design decisions you took are flawed. But to answer your specific question, which should get your use-case to work correctly, but at a impact to performance cost:
You can set spring beans to various scopes (relevant for your usecase: prototype / request or session), which will modify when spring beans get instanced. The default behaviour is one bean per spring container (singleton), hence the concurrency issues. See https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html
The easiest solution is simply to not store the dataset in a class field.
Instead, store the dataset in a local variable and pass it as an argument to other functions, this way there will not be any concurrency problems, as each call stack will have it's own instance.
Example:
public void entryPoint(String arg1, int arg2, Structure arg3) {
// Store the dataset in a local variable, avoiding concurrency problems
Dataset dataSet = gatherDataSet(String ar1);
// Treat the data passing dataset as an argument
subMethodOne(arg1, dataset);
subMethodTwo(arg2, dataset);
subMethodThree(arg3, dataset);
}
Use synchronized modifier for it.
As "Synchronization plays a key role in applications where multiple threads tend to share the same resources, especially if these resources must keep some kind of sensitive state where manipulations done by multiple threads at the same time could lead the resource to become in an inconsistent state."
public void someMethod() {
synchronized (object) {
// A thread that is executing this code section
// has acquired object intrinsic lock.
// Only a single thread may execute this
// code section at a given time.
}
}

When to use Spring prototype scope?

I want to know when should I exactly use the prototype scope in Spring? I have understood that singleton returns the same object instance if the bean is requested for.
Then why should we consider prototype?
Explanations with examples would help a lot to understand the need for it.
To be clear simple definitions:
Prototype scope = A new object is created each time it is injected/looked up. It will use new SomeBean() each time.
Singleton scope = The same object is returned each time it is injected/looked up. Here it will instantiate one instance of SomeBean and then return it each time.
Prototype bean is created at the time of usage. So when you would like to have stateful beans there is a strong need sometimes to have prototypes scope or when you don't want to cache any values in beans. Prototype bean can be associated with one session or some call.
Example:
A data access object (DAO) is not typically configured as a prototype, because a typical DAO does not hold any conversational state; it was just easier for this author to reuse the core of the singleton diagram.
There are some interesting use cases by using scope prototype you will build a better and reliable application design/architecture, for example, a real-time system.
Imagine that you must build a real-time system for vehicle tracking, and you will have 2.000.000 cars sharing information every 5 seconds,
In the server side, you will work with two or more distinct group of configurations, one for Cars and another one for Trucks.
Based on this simple example, if you design your application to work with distinct configuration groups in memory through the prototype pattern you will achieve a better performance.
So, in this case, whenever the server receives a new message from a Truck, for example, the server will get the instance of the configuration in memory from a hashmap of instances of VehicleGrupConfiguration and then apply the configuration behavior that this message must have, e.g: like time-out, retry... and etc.
I would like to highlight that there are many ways to implement this situation, but this example shows that a prototype pattern is very powerful in matters of performance and design patterns.
As the documentation says, creating a bean Foo with prototype scope is same as calling:
Foo foo = new Foo(dependency1, dependency2, ...);
foo.initialize(dependency7, dependency8...);
The only good reason to use a prototype scope bean instead of new that is when the dependencies used for creation and initialization of the instance should be kept outside the code that needs a new instance.
As an example:
// need to explicitly mention dependencies here
public void createdWithNew(Dependency dependency1, Dependency dependency2) {
Foo foo = new Foo(dependency1, dependency2, ...);
foo.doSomething();
}
// Dependencies managed in class Foo by Spring
public void createdWithSpring(Foo foo) {
foo.doSomething();
}
An example is if you wanted to write persistence code similar to EJB2 Java Entity beans, such as
Person p = ...
p.setName("John Doe");
p.save(); // write to DB
Instead of using the JPA way
Person p = new Person();
p.setName("John Doe");
personService.save(p); // write to DB
In the entity bean code style, the person instance needs to know how it should be persisted, so it needs to be injected with persistence details that the code writing a person should not be aware about.
Another example:
If you want to use the non-threadsafe SimpleDateFormat Java class in many places of your application, with a format pattern from a configuration file(maybe using different formats depending on other conditions). Instead of creating a new format instance in all those places loading also the formatting string from a file (or spring property), you could use the prototype scope to get a fresh instance every time, with the details of setting the common format being in one place.

Can DAO's hold state information

May be this might sound a bit mundane, can someone tell me if there is any good practise which says DAO's should not store state information i.e. non static non final member variables? Most of the DAO's that i have come accross mainly contain only static and final variables.
public class CustomerDAO extends CommonDAO{
private String txnid;
private String txnName;
getters....setters..
}
For me, a DAO is "just a pipe", made to encapsulate database communication. It constructs and executes the queries or/and proxies the EntityManager, so at least for JPA, no state is needed, except for the EntityManager instance. Queries do not depend on each other directly.
So I would put the question the other way round - What sensible state could a DAO have?
Strongly no on this one: DAOs' whole reason for existing is to provide a stateless range of DB access methods. Most developers reading your code would be very surprised to find any state.
Also, state as you are illustrating is not thread safe - you could get into a right mess doing that kind of thing.
DAOs are usually implemented following the singleton pattern - meaning there is only one instance of the DAO for every single entity, so state information would be shared among all parts of the application using the DAO

Seam outjections will be removed?

Jacob Orshalick (author of Seam Framework: Experience the Evolution of Java EE ) said:
Outjection allows you to make variables available from the current context for injection or access through EL. This can be beneficial if you want to loosely couple several components that inject the same context variable (like the current user, the hotel being booked, etc). If you want to avoid outjection, an alternative is to use an #Factory method or set the value directly into the context through: Contexts.getConversationContext().set("myVarName", myVar)
Another benefit is performance. By outjecting a value to the context, you can bypass having to pass through your component to get that value. This is especially applicable in the case of data tables with JSF (see this discussion). But, as you will see in the discussion you could also use #BypassInterceptors to achieve the same benefit.
Outjection is really a convenience, but the same benefits can definitely be achieved through other means. Do note that outjection was not included in Web Beans and will either be deprecated or completely removed in Seam 3, so this is further reason to avoid it when possible.
We have an application with a lot of outjections and we've started to get rid of them. He said:
but the same benefits can definitely be achieved through other means.
but which are these other means? How to remove the outjections? In ASP.NET for instance you have session variables. In Seam, you can outject var in session (a benefit in some situations).
Or page scope: (for instance in jsf cycle the backing bean is called multiple times (sometimes). You have an account which is loaded from an accountId page param. You can load the account, outject it with a page scope and you can use its properties greatly. OR (to avoid outjection) is to have a loadAccount() method where you take the account from the db whenever you need it...WORST!)
I do not think that:
Contexts.getConversationContext().set("myVarName", myVar)
is a method of how to avoid outjection.
This only calls the same context where the outjected variable is saved and modifies it in a profound way (i think it's exactly what #Out do in the background).
Question 1: What do you think guys about their intention? Do you have specific info about how they will replace it?
Question2: How do you avoid the use of outjection?
Thanks in advance.
I think the best way you can achieve "outjection" is by using #Factory. Its advantage:
It can be #In-jected into another component
It can create any value, not just component instance
It calculate the value once, and just once
It can be triggered by JSF page (I am not sure whether you must enable Seam Transaction Management in order to get this feature)
So if you have a JSF page that needs to access a #Factory more than one time, It is calculated just once. If a value needs to be calculated each time it is requested, so you need a #Unwrap method. For instance, #{currentDate} built-in component is implemented as follows
#Name("org.jboss.seam.faces.facesContext")
#Scope(ScopeType.STATELESS) // ScopeType.STATELESS is similar to Spring prototype scope
public class CurrentDate {
#Unwrap
public Date getCurrentDate() {
return new java.sql.Date(System.currentTimeMillis());
}
}
regards,
To avoid outjection just add a getter to your field in your backing bean, so instead of:
#Name("myBean")
public class MyBean{
#Out
private SomeBean someBean;
}
you will have:
#Name("myBean")
public class MyBean{
private SomeBean someBean;
public SomeBean getSomeBean(){
return someBean;
}
}
and in your xhtml/jsp file you will have to call the getter instead but this have some issues too because everytime you call the getter all the Seam Interceptors will be applied to that call so you probably will need to add #BypassInterceptors to prevent that from happening.
And yes I also think that
Contexts.getConversationContext().set("myVarName", myVar)
is just doing what outject does but manually.

Categories