I'm back to building my Managed-Bean of a hashMap. ( Creating a HashMap of type <String , Object> ) I have defined a class
public class AppProperties {
private String appRepID;
private String helpRepID;
private String ruleRepID;
private String filePath;
private Vector formNames;
private Database appDB;
// all the getters and setters
}
The managed bean will create an Application Scope variable of the hashMap. In the constructor of the Bean I build the the values for each Application (the key) by collecting all the info from a number of different places. The repIDs are pretty straight forward. My question/concern is it wise to store the appBD in the Application Scope variable. I have read that one should never store a Notes Object in a Scoped Variable would that be an issue here? Secondly, if that is the case I could add a method to the AppProperties that would open the DatabaseByReplicaID when ever the method to get the Application Database is called, which adds a fair bit of overhead to the process as the database object will get called many many time in the life cycle of the application.
Right, you shouldn't store Notes objects in scope variables and properties of beans.
Because They are not serializable (a must for certain scopes) and they will be recycled between lifecycles. More precisely, since they are based on C-handles, XSP engine creates Notes objects between request-response cycle and when response written back to the user, they are all going to be recycled. Trying to keep them in the memory will make them 'toxic' for your server.
You can define a method in your bean (like GetHelpDb()), create and return it whenever you need. It's not a huge performance cost. Because Domino server implements caching for databases. When you open a database over and over again will not generate additional disk I/O.
The best practice for interacting with Notes data in such situation would be caching. I frequently use this approach in my applications. You might get values in a single method, cache them into HashMap(s) and get them from the map when you need. Using getter method, you may also check a time-based value to handle time-outs.
Related
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.
}
}
I'm translating an application based on REST using Spring Framework. Now I need to translate some responses based on the language of the request. For example:
/get-me-an-answer/?lang=es Spanish
/get-me-an-answer/?lang=en English
/get-me-an-answer/?lang=fr French
I have the variable language_code as a static variable in a class named Translang
class Translang {
...
public static String language_code = null;
...
}
The problem is with multithreading, when a new request come will change the language and if another previous request is executing can probably answer in the language modified and not in the original language it requested.
That's the reason of my question: How can I have a global variable in Spring per request to avoid this problem?
Seems that ThreadLocal is what you are looking for as per request is performed by a separate thread.
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. ThreadLocal instances are typically private
static fields in classes that wish to associate state with a thread
(e.g., a user ID or Transaction ID).
I would suggest to implement a context that navigates throw the flow of your request, so with this, you will pass this context among the entire transaction, once you have that domain element, you need to create a new one by each request that you receive. Currently your class is not thread safe, this can be fixed also changing the scope of your bean.
In this link: http://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable
they say:
When the above POJO is defined as a bean in a Spring IoC container, the bean instance can be made 'cacheable' by adding merely one line of XML configuration.
Without using a caching framework, I would just declare Weather and List as static and that would have taken care of caching.
So my question is that if I want to just have the Weather and List<Location> to be cached, then why would I cache the entire DAO?
Also behind the scenes, does the annotation #Cacheable turn Weather and List<Location> into static variables?
This is the code in question:
public interface WeatherDao {
public Weather getWeather(String zipCode);
public List<Location> findLocations(String locationSearch);
}
public class DefaultWeatherDao implements WeatherDao {
#Cacheable(cacheName="weatherCache")
public Weather getWeather(String zipCode) {
//Some Code
}
#Cacheable(cacheName="locationSearchCache")
public List<Location> findLocations(String locationSearch) {
//Some Code
}
}
I don't quite understand your points about static variables. In essence there is a map from zipCode to Weather and similar from locationSearch to List<Location>. This map can come from a database, file, external API, etc.
Do you want to create a map with all possible arguments as keys and corresponding values? Sure, you can, but it has several drawbacks:
you put a lot of pressure on your heap. In many cases the amount of data might never fit into memory, or even on your disk (think: caching Google search engine by storing every possible search query and list of hits)
most likely you won't use most of the keys, ever. Why store them in memory?
what about eviction? I bet these methods tend to return different weather for the same ZIP code over the time...
Since I don't fully understand your arguments, let me explain briefly what happens behind the scenes when getWeather() is called:
transparent proxy intercepts getWeather() call and looks up weatherCache
in that cache it uses zipCode argument as cache key
if such entry exists (of type Weather) it is returned immediately
if the above is not the case, control is delegated to the real getWeather() method. It can call some API, run database query or do some lengthy computations
the result of getWeather() is placed in the weatherCache for future reference.
No static is involved here.
BTW Spring 3.1 introduced caching abstraction layer that probably makes this Google Code project obsolete. It looks the same and allows seamless integration with different cache implementations.
I am asking very generic question and the answer can vary from requirement to requirement, but for "general" or "rule of thumb", can we say the following is a good design rule:
The classes to be cached (static/reference data) should be designed as
immutable, with exceptions reasoned.
What could be design/performance issues with the above statement, if this is not true?
#JohnB has a good answer about the underlying data.
If, however, the question is referring to the immutability of the cached classes themselves (which are holding the data in the cache), then the answer is that mutable classes can cause thread-safety issues if the instances of the classes are referenced by multiple threads (as can often happen with data shared via a cache). Additionally, "accidental" modification of the data may occur, where a shared instance is unintentionally modified (because the modifying code did not know that the data was shared).
This is because of what a cache does, which is hold data rather than retrieving it from the data source again. For example, you query the database for a value then put it in a memory-based cache so you don't have to query the DB again. However, if the value in the DB can change then the value in the cache will be out of date and your application will be using the wrong data.
Therefore, caching is best if the data cannot change during the live of the application. If the data can change, then a strategy must be developed to regularly check to see if the data has changed.
What jtahlborn is explaining in other words : an immutable class will provide methods to obtain "static" data.
If your class is immutable, you will NOT have setters except the parameters in the constructor.
Take care making this : immutable classes are not made to be used only once, it would result in a performance loss, since copies of inner attributes have to be done each time you access the get... methods.
Example :
class MyImmutableThing {
private final String myProperty;
MyImmutableThing(String myProperty) {
this.myProperty = myProperty;
}
String obtainMyProperty() {
return myProperty;
}
// note there is no mean to modify the myProperty value : the original value remains ;)
// That's it !
}
Let's say you have a Client and a Server that wants to share/synchronize the same Models/Objects. The models point to each other, and you want them to keep pointing at the same object after being sent/serialized between the client and the server. My current solution roughly looks like this:
class Person {
static Map<Integer,Person> allPeople;
int myDogId;
static Person getPerson(int key){
return allPeople.get(key);
}
Dog getMyDog() {
return Dog.getDog(myDogId);
}
}
class Dog {
static Map<Integer,Dog> allDogs;
int myOwnersId;
static Dog getDog(int key) {
return allDogs.get(key);
}
Person getMyOwner() {
return Person.getPerson(myOwnersId);
}
}
But i'm not too satisfied with this solution, fields being integer and stuff. This should also be a pretty common problem. So what I'm looking for here is a name for this problem, a pattern, common solution or a library/framework.
There are two issues here.
Are you replicating the data in the Client and the Server (if so, why?) or does one, the other, or
a database agent hold the Model?
How does each agent access (its/the) model?
If the model is only held by one agent (Client, Server, Database), then the other agents
need a way to remotely query the model (e.g., object enumerators, getters and setters for various fields)
operating on abstract model entities (e.g, model element identifiers, which might be implemented
as integers as you have done).
Regardless of who holds the model (one or all), each model can be implemented naturally.
THe normal implementation has each object simply refer to other objects using normal object references,
as if you had coded this without any thought of sharing between agents, and unlike what
you did.
You can associate an objectid with each object, as you have, but your application
code doesn't need to use it; it is only necessary when referencing a remote copy of
of the model. Whether this objectid is associated with each object as a special
field, a hash table, or is computed on the fly is just an implementation detail.
One way to handle this is to compute the objectid on-the-fly. You can do this
if there is a canonical spanning tree over the entire model. In this case,
the objectid is "just" the path from root of the spanning tree to the location
of object. If you don't have a spanning tree or it is too expensive to compute,
you can assign objectids as objects are created.
The real problem with a duplicated, distributed model as you have suggested you have,
is keeping it up to date with both agents updating it. How do you prevent
one from creating an object (an assigning an objectid) at the same time
as the other, but the objects being created are different with the same objectid,
or the same with with different Objectids? You'll need remote locking
and signalling to keep the models in sync (this is the same problem as
"cache coherency" for multiple CPUs; just think of each object as acting like a cache line). The way it is generally solved
is to designate who holds the master copy (perhaps of the entire model,
perhaps of individual objects within the model) and then issue queries,
reads, reads-with-intent-to-modify, or writes to ensure that the
"unique" entire model gets updated.
The only solution I am aware of is to send the complete structure, i.e. Dogs and Persons over the network. Then they will end up pointing to the correct copy on the other side of the network. The implementation of this solution however depends on a lot of circumstances. For example when your inclusion relation defines a tree you can go at this problem differently than if it is a graph with cycles.
Have a look at this for more information.
I guess one can use the proxy pattern for this.