How do i measure how long a client has to wait for a request.
On the server side it is easy, through a filter for example.
But if we want to take into accout the total time including latency and data transfer, it gets diffcult.
is it possible to access the underlying socket to see when the request is finished?
or is it neccessary to do some javascript tricks? maybe through clock synchronisation between browser and server? are there any premade javascripts for this task?
You could wrap the HttpServletResponse object and the OutputStream returned by the HttpServletResponse. When output starts writing you could set a startDate, and when it stops (or when it's flushed etc) you can set a stopDate.
This can be used to calculate the length of time it took to stream all the data back to the client.
We're using it in our application and the numbers look reasonable.
edit: you can set the start date in a ServletFilter to get the length of time the client waited. I gave you the length of time it took to write output to the client.
There's no way you can know how long the client had to wait purely from the server side. You'll need some JavaScript.
You don't want to synchronize the client and server clocks, that's overkill. Just measure the time between when the client makes the request, and when it finishes displaying its response.
If the client is AJAX, this can be pretty easy: call new Date().getTime() to get the time in milliseconds when the request is made, and compare it to the time after the result is parsed. Then send this timing info to the server in the background.
For a non-AJAX application, when the user clicks on a request, use JavaScript to send the current timestamp (from the client's point of view) to the server along with the query, and pass that same timestamp back through to the client when the resulting page is reloaded. In that page's onLoad handler, measure the total elapsed time, and then send it back to the server - either using an XmlHttpRequest or tacking on an extra argument to the next request made to the server.
If you want to measure it from your browser to simulate any client request you can watch the net tab in firebug to see how long it takes each piece of the page to download and the download order.
Check out Jiffy-web, developed by netflix to give them a more accurate view of the total page -> page rendering time
I had the same problem. But this JavaOne Paper really helped me to solve this problem. I would request you to go thru it and it basically uses javascript to calculate the time.
You could set a 0 byte socket send buffer (and I don't exactly recommend this) so that when your blocking call to HttpResponse.send() you have a closer idea as to when the last byte left, but travel time is not included. Ekk--I feel queasy for even mentioning it. You can do this in Tomcat with connector specific settings. (Tomcat 6 Connector documentation)
Or you could come up with some sort of javascript time stamp approach, but I would not expect to set the client clock. Multiple calls to the web server would have to be made.
timestamp query
the real request
reporting the data
And this approach would cover latency, although you still have have some jitter variance.
Hmmm...interesting problem you have there. :)
Related
I am writing a tool, which should be able to measure the execution time of a servlet's method from client side. Not the whole servlet's, only one method's.
To measure the running time of the whole servlet, I set a start-time then created a URLConnection with the servlet's URL, opened the connection, got the inputstream, read the inputstream, closed the connection and then set an end-time and calculated the elapsed time with a subtraction.
But this time I'd like to measure only one method of the servlet and avoid calculating parameter reading and checking and such thing. I guess it's only possible in the servlet itself, but I need the measured value sent back to the client side program. Is it possible somehow? Or am I on the wrong path?
Thanks in advance!
No, this is not possible. You do not have control over what and how is executed on the server side being on the client side.
In general I would use Java Melody for such things. Take a look, but that is not what you are asking.
Doing it yourself sounds imprecise. Maybe you can test the time against a call to a annother empty method.
Because of browser compatibility issues, I have decided to use long polling for a real time syncing and notification system. I use Java on the backend and all of the examples I've found thus far have been PHP. They tend to use while loops and a sleep method. How do I replicate this sort of thing in Java? There is a Thread.sleep() method, which leads me to...should I be using a separate thread for each user issuing a poll? If I don't use a separate thread, will the polling requests be blocking up the server?
[Update]
First of all, yes it is certainly possible to do a straightforward, long polling request handler. The request comes in to the server, then in your handler you loop or block until the information you need is available, then you end the loop and provide the information. Just realize that for each long polling client, yes you will be tying up a thread. This may be fine and perhaps this is the way you should start. However - if your web server is becoming so popular that the sheer number of blocking threads is becoming a performance problem, consider an asynchronous solution where you can keep a large numbers of client requests pending - their request is blocking, that is not responding until there is useful data, without tying up one or more threads per client.
[original]
The servlet 3.0 spec provides a standard for doing this kind asynchronous processing. Google "servlet 3.0 async". Tomcat 7 supports this. I'm guessing Jetty does also, but I have not used it.
Basically in your servlet request handler, when you realize you need to do some "long" polling, you can call a method to create an asynchronous context. Then you can exit the request handler and your thread is freed up, however the client is still blocking on the request. There is no need for any sleep or wait.
The trick is storing the async context somewhere "convenient". Then something happens in your app and you want to push data to the client, you go find that context, get the response object from it, write your content and invoke complete. The response is sent back to the client without you having to tie up a thread for each client.
Not sure this is the best solution for what you want but usually if you want to do this at period intervals in java you use the ScheduleExecutorService. There is a good example at the top of the API document. The TimeUnit is a great enum as you can specify the period time easily and clearly. So you can specify it to run every x minutes, hours etc
In designing my GWT/GAE app, it has become evident to me that my client-side (GWT) will be generating three types of requests:
Synchronous - "answer me right now! I'm important and require a real-time response!!!"
Asynchronous - "answer me when you can; I need to know the answer at some point but it's really not all that ugent."
Command - "I don't need an answer. This isn't really a request, it's just a command to do something or process something on the server-side."
My game plan is to implement my GWT code so that I can specify, for each specific server-side request (note: I've decided to go with RequestFactory over traditional GWT-RPC for reasons outside the scope of this question), which type of request it is:
SynchronousRequest - Synchronous (from above); sends a command and eagerly awaits a response that it then uses to update the client's state somehow
AsynchronousRequest - Asynchronous (from above); makes an initial request and somehow - either through polling or the GAE Channel API, is notified when the response is finally received
CommandRequest - Command (from above); makes a server-side request and does not wait for a response (even if the server fails to, or refuses to, oblige the command)
I guess my intention with SynchronousRequest is not to produce a totally blocking request, however it may block the user's ability to interact with a specific Widget or portion of the screen.
The added kicker here is this: GAE strongly enforces a timeout on all of its frontend instances (60 seconds). Backend instances have much more relaxed constraints for timeouts, threading, etc. So it is obvious to me that AsynchronousRequests and CommandRequests should be routed to backend instances so that GAE timeouts do not become an issue with them.
However, if GAE is behaving badly, or if we're hitting peak traffic, or if my code just plain sucks, I have to account for the scenario where a SynchronousRequest is made (which would have to go through a timeout-regulated frontend instance) and will timeout unless my GAE server code does something fancy. I know there is a method in the GAE API that I can call to see how many milliseconds a request has before its about to timeout; but although the name of it escapes me right now, it's what this "fancy" code would be based off of. Let's call it public static long GAE.timeLeftOnRequestInMillis() for the sake of this question.
In this scenario, I'd like to detect that a SynchronousRequest is about to timeout, and somehow dynamically convert it into an AsynchronousRequest so that it doesn't time out. Perhaps this means sending an AboutToTimeoutResponse back to the client, and force the client to decide about whether to resend as an AsynchronousRequest or just fail. Or perhaps we can just transform the SynchronousRequest into an AsynchronousRequest and push it to a queue where a backend instance will consume it, process it and return a response. I don't have any preferences when it comes to implementation, so long as the request doesn't fail or timeout because the server couldn't handle it fast enough (because of GAE-imposed regulations).
So then, here is what I'm actually asking here:
How can I wrap a RequestFactory call inside SynchronousRequest, AsynchronousRequest and CommandRequest in such a way that the RequestFactory call behaves the way each of them is intended? In other words, so that the call either partially-blocks (synchronous), can be notified/updated at some point down the road (asynchronous), or can just fire-and-forget (command)?
How can I implement my requirement to let a SynchronousRequest bypass GAE's 60-second timeout and still get processed without failing?
Please note: timeout issues are easily circumvented by re-routing things to backend instances, but backends don't/can't scale. I need scalability here as well (that's primarily why I'm on GAE in the first place!) - so I need a solution that deals with scalable frontend instances and their timeouts. Thanks in advance!
If the computation that you want GAE to do is going to take longer than 60 seconds, then don't wait for the results to be computed before sending a response. According to your problem definition, there is no way to get around this. Instead, clients should submit work orders, and wait for a notification from the server when the results are ready. Requests would consist of work orders, which might look something like this:
class ComputeDigitsOfPiWorkOrder {
// parameters for the computation
int numberOfDigitsToCompute;
// Used by the GAE app to contact the requester when results are ready.
ClientId clientId;
}
This way, your GAE app can respond as soon as the work order is saved (e.g. in Task Queue), and doesn't have to wait until it actually finishes calculating a billion digits of pi before responding. Your GWT client then waits for the result using the Channel API.
In order to give some work orders higher priority, you can use multiple task queues. If you want Task Queue work to scale automatically, you'll want to use push queues. Implementing priority using push queues is a little tricky, but you can configure high priority queues to have faster feed rate.
You could replace Channel API with some other notification solution, but that would probably be the most straightforward.
I want to push the data to the jsp for every 2 seconds, with out client requesting it.
I am using Spring with Hibernate here.
I am displaying google maps marker, and I want to update the marker location for every 2 seconds by getting the data from database, however I have done getting the data from database for every 2 seconds, but I am unable to push that data to this jsp.
#Scheduled(fixedRate = 2000)
public void getData(){
// TODO Auto-generated method stub
DeviceDetails deviceDetails = realTimeDataDAO.getDeviceDetails(deviceId);
System.out.println(deviceDetails);
}
I have to display some data after every 2 seconds. Can anyone tell me how to do that?
any one knows about Comet Ajax Push technology, will it work in this scenario?
You have a number of choices.
Polling - as mentioned in other answers you could simply have javascript in the client constantly poll the server every 2 seconds. This is a very common approach, is simple and will work in the large majority browsers. While not as scaleable as some other approaches setup correctly this should still be able to easily scale to moderate volumes (probably more users than you'll have!).
Long polling - Also known as Comet this is essentially a long lived request. The implementation of this will vary depending on your app server. see here for Tomcat: http://wiki.apache.org/tomcat/WhatIsComet or Jetty bundles some examples.
HTML 5 solutions while the web is traditionally request response based - event based processing is part of the HTML 5 spec. As you events seem to be only one way (server -> client) Consider using Event sources. See: http://www.html5rocks.com/en/tutorials/eventsource/basics/ or again the Jetty examples. Caveats here are that only modern browsers and some app servers support these methods - e.g. Apache doesn't natively support websockets.
So to sum up - my gut feeling is that your needs and for simplicity a polling approach is fine - don't worry too much initially about performance issues.
If you want to be on the cutting edge, learn new thing and you have control over your app server and frameworks then I'd go for the HTML 5 approach.
Comet is kind of a half way house between these two.
Your best bet with Spring is to store the results of the scheduled query into a bean in memory, then have another request-scope bean get that stored result in a method that is web accessible, and return it as text (or JSON). Alternatively you could query the DB everytime an update is requested.
Then, you can make a timed async request from your page (You may want to use YUI Connection Manager for that), read the response and use the panTo method from google.maps.Map to update your map location.
As you can see, the solution is split in a Java and a JavaScript portion.
For the Java side, you must create a controller that performs the query to the database (or better yet, delegates that task to another layer) and returns the results as JSON, you can use http://spring-json.sourceforge.net/ for that. It's a bit complex in Spring so you might want to instead create a simple servlet that returns the data.
For the Javascript side, once you have a working endpoint that returns the JSON data, using YUI Connection Manager and the google maps api:
function update(){
var callback = {
success: function (o) {
var response = YAHOO.lang.JSON.parse(o.responseText);
map.panTo({lat: response.lat, lng: response.longi}); // map is the google.maps.Map representing your map
},
failure: function (o) {
}
}
var sUrl = '/getData.htm'; // This is the request mapping for your bean
YAHOO.util.Connect.asyncRequest('GET', sUrl,callback);
}
function init(){
setTimeout("update()", 2000);
}
The best way to do it is to have the client send an new request every 2 second, and then display the new data.
Since you use HTTP i assume you use javascript on the client side, so you need a timer in your javascript which fire every 2 second, and then let the javascript perform an ajax call to the server to get the data which it can then display.
Try a TimerTask or ThreadExecutor (look at the scheduled implementation).
Well, if you want to implement above solution in web application I am not sure but I think you cannot do it this way. HTTP is a request/response protocol and when the server finish sending one response it cannot initiate on its own sending a new response. In short words: one request from client - one response from server.
I think that you should use AJAX (asynchronous Javascript requests) so as to ask server every 2 second for a new data and if necessary update the DOM (website HTML tags structure).
I have had good experience with WebSockets. Very fast, low overhead bi-directional protocol between server and browser. Not sure what's your backend but Jetty supports it very well. Just have a timer process on the backend which would iterate over all active WebSockets sessions and push updates. There are plenty example on the net of how to use Websockets.
Things to keep in mind:
WebSockets not supported by all browsers (Chrome and Safari seems to be the best supported)
WebSockets traffic doesn't traverse all proxies
Depending on your requirements it might or might not be acceptable.
There are some projects like Atmosphere which tries to abstract browser/server differences in websockets support with graceful fallback to Comet. It might worth to look at.
//Initialize this somewhere
ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
exe.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
//The executor service tries to run 2 seconds after it last finished
//If you code takes 1 second to run this will effectively run every 3 seconds
}
}, 0, //this is the initial delay
2, //this is the consecutive delay
TimeUnit.SECONDS);
exe.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//The executor service tries to run this every 2 seconds
//If you code takes 1 second to run this will still run evey 2 seconds
}
}, 0, //this is the initial delay
2, //this is the period it tries to run in
TimeUnit.SECONDS);
You need to send the data from server to client for every 2 secs. And already you know how to gather the data for every 2 seconds at the server side.
If this is all you need, the "Ajax streaming" will help you. This is on the client side. From server side for every 2 seconds you need to write the data and flush it.
Searching for this term will give you lot of examples. But remember all modern browsers will use one approach and all IE browsers will use IFrame approach to implement streaming.
In the first case, you need to make XHR request and peek the response and process it.
Here are a few examples: (I didt have time to go through them completely)
http://ajaxpatterns.org/HTTP_Streaming
http://developers.cogentrts.com:8080/DH_ajax_1.asp
U can use ajax call.
As you can write code from Javascript that will send the request for every 2 seconds,but for this your server should be quick responsive for this type of request.
Well I guess this will help you.
If your server gets more than 1000 users then your application server will fail. I recommend you use NON Blocking Input Output methods supported using Jetty Server only to host the requests made for this purpose and use your normal EE Server for other applications.
I am trying to perform some computations on a server. For this, the client initially inputs some data which I am capturing through Javascript. Now, I would perhaps make a XMLHttpRequest to a server to send this data. Let's say the computation takes an hour and the client leaves the system or switches off the system.
In practice, I would use perhaps polling from the client side to determine if the result is available. But is there some way I could implement this in the form of a call back, for instance, the next time the client logs in, I would just contact the client side Javascript to pass the result... Any suggestions? I am thinking all this requires some kind of a webserver sitting on the client side but I was wondering if there's a better approach to do this.
Your best bet is to just poll when the user gets to the web page.
What I did in something similar was to gradually change my polling time, so I would start with several seconds, then gradually increase the interval. In your case, just poll after 15 minutes, then increase every 5 minutes when it fails, and if the user closes the browser then you can just start the polling again.
If you want some callback, you could just send an email when it is finished, to let the user know.
Also, while you are doing the processing, try to give some feedback as to how far you have gone, how much longer it may be, anything to show that progress is being made, that the browser isn't locked up. If nothing else, show a time with how long the processing has been going on, to give the user some sense of progress.