Play framework concepts - java

Could someone explain how the web apps work on play framework example? The things I misunderstand:
1)Which part of the code(I mean code from examples listed on play framework site) allows many users to use the same app at same time?
2)For example I have a program : a textField, button and list. Write in textfield, press button and the text is added to the list. Every user should have own list, but where should I store the data if it's objects, in memory? In DB? In session/cookies? And how this data should be recognized, by session of? Are there any good examples?

I think you should read the documentation and search the web a bit more about Play to be honest. Here are a few pointers:-
Play will use a default thread pool to serve requests. All actions are asynchronous - meaning (as long as you do not block a thread in the action) a Play app should be able to serve a large volume of requests (depending on your machine resources), as these threads get quickly reused to serve other requests
Play is designed to be stateless so no Session (in context of Java servlet session that is). Play does not use Java servlet spec. (actually one of the original drivers Play was created was of limitations of Servlet spec)
In terms of your own application, what are you going to do with that data you have collected later? What do you need it for? That should help you determine where to store it (if at all). If you want it just for session scope then you could use session cookie - see the docs). If you want it later (ie. when user comes back to site) then you could put it in a store of some kind. Again, see the docs.
There are loads of articles on Play's architecture. And the official docs are quite good at pointing you in the right direction for most use cases.
The Lightbend has some good resources and there are loads of Activator templates to provide codes samples.
Here is the simple CRUD template which might help you.

Related

Any properties needs to be changed for multi user application

Please consider me as a novice and this is my first web app I am creating.
I am planning to develop a web application where the traffic I am expecting is around 50 users will access the application at a single time.
The webapp is developed with Vaadin (for UI) and respective business logic implemented with Java. DB used would be MySQL. The war will be deployed in Tomcat.
So, my question is do I need to modify anything in Tomcat properties or anywhere to make the web app as multi user application (i.e. each users need to access and use application as though they are only one using the application)?
I tried to access a prototype developed using Vaadin in both Chrome and Firefox and could see both sessions running without an impact on another.
But please let me know suggestions.
You must keep in mind that even if tomcat and vaadin manage multiple sessions, your server application will have only 1 instance. So if you use singletons, static methods or fields, use them with care: they should never hold session-dependant content. Try to favour stateless methods over statefull.
Apart from that, there shouldn't be any problem.
It should not have any code changes if you handle the session and your business logic with statefulness properly.
There might be some configuration changes, like increasing the database connection pool size, it depends on what kind of connection pooling you are using and what is the default size etc.
Apart from that it should work just fine.
Vaadin is built on top of Jakarta Servlet technology (formerly known as Java Servlet). See Wikipedia. Indeed, Vaadin is a servlet, a much bigger and more sophisticated servlet than most.
Within a Java Servlet container (engine) such as Apache Tomcat or Eclipse Jetty, any particular servlet has only a single instance running. If three requests from three users arrive at the same time, there are three threads running through that same single instance for that particular servlet. So a servlets are inherently a highly threaded environment.
If you share any variables or resources between those threads, you must be very careful. That means mandatory reading, rereading, and fierce study of the book Java Concurrency in Practice by Brian Goetz, et al.
While the Web and HTTP were designed to be stateless delivery of single documents, that original vision has been warped by the desire to make web apps. To maintain state, a servlet automatically maintains a session. Vaadin represents this session state in its VaadinSession object. All data in all the forms, along with business logic, running for each user is maintained as part of that session.
Depending on your particular Vaadin app, and when multiplied by the number of concurrent users, this may add to a large amount of memory. You should monitor your server to make sure you have enough available RAM on your server.
do I need to modify anything in Tomcat properties or anywhere to make the web app as multi user application (i.e. each users need to access and use application as though they are only one using the application)?
No, nothing for you to set or enable. Tracking the requests/responses and session for each user is the very purpose of a servlet container. From the moment it launches, every servlet container expects multiple users. As a Servlet, Vaadin is built to expect multiple users as well. The only trick is making your own code thread-safe, hence the book suggestion.
I tried to access a prototype developed using Vaadin in both Chrome and Firefox and could see both sessions running without an impact on another.
Concurrency problems can be very tricky to detect and debug. Often potential problems occur on the random chance of coincidental timing. You need to focus on properly designing your code in the first place, rather than relying on testing. Again, hence the book recommendation.
Of special note, since you mentioned using a database, is JDBC drivers. Deploying them in a Servlet environment can be tricky. Basically you need to not bundle them within your Vaadin web app WAR file. Instead, deploy the JDBC driver separately within a shared library folder within Tomcat. If using Maven to drive your project, direct Maven in the POM file to give the dependency for your JDBC driver a scope of provided. This has nothing to do with Vaadin specifically, it applies to all servlets. Search Stack Overflow as this issue has been extensively addressed.

Combining java spring/thread and database access for time-critical web applications

I'm developing an MVC spring web app, and I would like to store the actions of my users (what they click on, etc.) in a database for offline analysis. Let's say an action is a tuple (long userId, long actionId, Date timestamp). I'm not specifically interested in the actions of my users, but I take this as an example.
I expect a lot of actions by a lot of (different) users par minutes (seconds). Hence the processing time is crucial.
In my current implementation, I've defined a datasource with a connection pool to store the actions in a database. I call a service from the request method of a controller, and this service calls a DAO which saves the action into the database.
This implementation is not efficient because it waits that the call from the controller and all the way down to the database is done to return the response to the user. Therefore I was thinking of wrapping this "action saving" into a thread, so that the response to the user is faster. The thread does not need to be finished to get the reponse.
I've no experience in these massive, concurrent and time-critical applications. So any feedback/comments would be very helpful.
Now my questions are:
How would you design such system?
would you implement a service and then wrap it into a thread called at every action?
What should I use?
I checked spring Batch, and this JobLauncher, but I'm not sure if it is the right thing for me.
What happen when there are concurrent accesses at the controller, the service, the DAO and the datasource level?
In more general terms, what are the best practices for designing such applications?
Thank you for your help!
Take a singleton object # apps level and update it with every user action.
This singleton object should have a Hashmap as generic, which should get refreshed periodically say after it reached a threshhold level of 10000 counts and save it to DB, as a spring batch.
Also, periodically, refresh it / clean it upto the last no.# of the records everytime it processed. We can also do a re-initialization of the singleton instance , weekly/ monthly. Remember, this might lead to an issue of updating the same in case, your apps is deployed into multiple JVM. So, you need to implement the clone not supported exception in singleton.
Here's what I did for that :
Used aspectJ to mark all the actions of the user I wanted to collect.
Then I sent this to log4j with an asynchronous dbAppender...
This lets you turn it on or off with log4j logging level.
works perfectly.
If you are interested in the actions your users take, you should be able to figure that out from the HTTP requests they send, so you might be better off logging the incoming requests in an Apache webserver that forwards to your application server. Putting a cluster of web servers in front of application servers is a typical practice (they're good for serving static content) and they are usually logging requests anyway. That way the logging will be fast, your application will not have to deal with it, and the biggest work will be writing a script to slurp the logs into a database where you can do analysis.
Typically it is considered bad form to spawn your own threads in a Java EE application.
A better approach would be to write to a local queue via JMS and then have a separate component, e.g., a message driven bean (pretty easy with EJB or Spring) which persists it to the database.
Another approach would be to just write to a log file and then have a process read the log file and write to the database once a day or whenever.
The things to consider are: -
How up-to-date do you need the information to be?
How critical is the information, can you lose some?
How reliable does the order need to be?
All of these will factor into how many threads you have processing your queue/log file, whether you need a persistent JMS queue and whether you should have the processing occur on a remote system to your main container.
Hope this answers your questions.

How stateful should a web application be at most?

I heard a web application should be as stateless as possible. But it seems to me very hard to realize this often. For instance, what if I:
Process a request
Redirect the user to the start page
Want to display the result of the request?
If the result is a little bit more complex, then just a string which could be passed as a parameter (or I don't want to include that information via URL), then I cannot combine 2. and 3.
The only solution I can think of here is keeping the information as states in the Java program.
But that would break with the rule of a stateles web application, wouldn't it?
I heard a web application should be as stateless as possible
What? There is state everywhere in a web app, both in the client and on the server. Frameworks like Sproutcore/Ember even have components called State Managers to manage, um, the state.
The server maintains some state in a user's session (typically).
Did you hear that HTTP is stateless? That's another story, and completely true. Also, it can be a good idea to write server side components that don't share state, due to threading concerns. But neither of those points should be taken to imply that your application doesn't have state.

GWT: Batching vs Disposability vs Statelessness

I recently watched several Google I/O videos where Google developers present GWT with respect to performance and security. In that video the speaker makes mention of several GWT-isms:
Client-side request "batching"
"Disposability"
The pursuit of GWT app "statelessness"
With respect to "batching" it seems like GWT can be configured to queue-up server-side RPC calls and send them all at once (instead of many tiny, performance-hindering calls). Unfortunately, I'm just not seeing the forest through the trees here: doe GWT handle batching for you, or do you have to write the logic that performs this bundling/batching? If you have to do it, what kinds of calls can/should be bundled? How do you know when its time to fire the batch off?
In GWT lingo, what does it mean when someone says:
"Clients and servers are disposable"; but
"Views" are not disposable
How does this concept of "batching" and "disposability" relate to GWT app "statelessness". By that, the speaker defined statelessness as:
Browser embodies the session (?!?!)
Server is stateless - except for caching (?!?!)
Client never notices a restart (?!?!)
If someone could help give me concrete understanding of these 3 items and how they relate to each other I think I'll start to "get gwt". Thanks in advance!
doe GWT handle batching for you, or do you have to write the logic that performs this bundling/batching? If you have to do it, what kinds of calls can/should be bundled? How do you know when its time to fire the batch off?
GWT-RPC has no batching mechanism. You can (relatively) easily add some by queueing "commands" in a list and then sending the list as a single GWT-RPC call. Some projects should do that for you with minimal effort (GWT-Platform for example).
RequestFactory on the other hand has batching built-in: you create a RequestContext instance and batch calls to it until you fire() it.
"Clients and servers are disposable"; but "Views" are not disposable
The first is related to statelessness (and, for example, with AppEngine, you don't control when a new server instance is created, shutdown or restarted: the server can disappear at any time, so don't keep state in memory).
The second is about performance: everything related to the DOM in the browser is slow, so constructing a new view (widgets stacked together) is heavy-weight (less so with Cell widgets though). As a result, you don't want to make them disposable, i.e. throw them away every now and then. You'll rather want to keep one view instance around that you reuse for the lifetime of the app.
Not exactly the same notion of "disposability".
Browser embodies the session (?!?!)
GWT is built of single-page apps. You can store state on the client simply in variables in your app; you don't need cookies or whatever to have the state shared between pages.
Server is stateless - except for caching (?!?!)
Storing session state on the server has a cost (state must be persisted –particularly if the server is disposable–, shared between servers –when you have a cluster / run in the cloud–, etc. you'll spend as many resources keeping existence of your session state as doing actual business logic).
Client never notices a restart (?!?!)
HTTP is a a disconnected protocol. If the server is restarted, the client won't know about it, and it shouldn't have to know about it.
If someone could help give me concrete understanding of these 3 items and how they relate to each other I think I'll start to "get gwt".
It's not about getting GWT, it's about getting the Web and getting single-page webapps, and how to scale them.
Whether they're made with GWT or jQuery on the client-side, and Java or Python or .NET on the server-side doesn't matter.
Read about REST, it sums it all.

Spring framework, how to load session in different project

I have a project. In the first project I set the session
in my first project I put here as code
req.getSession().setAttribute("x", name);
return "ses";
In second project I put here
model.addAttribute("ses", req.getSession().getAttribute("x"));
return "oses";
but session is not appear.
How to make a session appear in different project with Spring framework?
You can't. (Well, perhaps you can setup some sort of session-replication, but you shouldn't do it. See related question)
You should use other forms of communication between your applications. The flow will be more complicated and will include exchange of tokens through (simple) web services, but it is better than relying on the server container, and on the fact that both applications will be run in the same container.
It'd be helpful to describe what you're actually trying to accomplish; as Bozho says you can't really share session objects between apps.
You could, however, use JMS (or any other intra-app comms) to send data from one app to another. You'll still need the capability to decide what to do with that data once you have it in the receiving app: how do I associate it with a given user, how do I get it into that user's session, and so on.
User information can be passed in the message, but there has to be some commonality between the two systems, some agreed-upon key, that can be used to figure out who the info belongs to.
Once you have that, the rest is mechanics; there are interesting games to be played, and it's easy to mess it up :)

Categories

Resources