Re: How to check if the client dropped the connection
awarnier wrote: aaime74 wrote: ... Hi. Kind of restarting from the beginning, I think that the first question to ask is whether whatever method which actually does the rendering of the maps, and which is heavy in terms of resources, is capable of being interrupted cleanly in the middle. Is it capable itself of checking regularly if it should continue doing the work ? Or else, if you shoot it down does it mop up after itself, or does it leave stuff to clean up all over the place ? I can cleanly stop the rendering process in almost any point of it. The issue is not stopping it, it's detecting the client connection was dropped. No matter what solution is adopted, one still depends on the ability to detect the client has dropped the connection, something that no one so far described how to check (I'm starting to wonder if there is a way at all). awarnier wrote: The (whenever possible) above refers to the fact that a number of things outside of your control can come in the way of such detection : proxies, firewalls and the like. If the ultimate client breaks the connection, it is not guaranteed that Tomcat itself would notice this right away. Ok, but let's say Tomcat is capable of that. How does one check from within the servlet that the connection has been dropped without writing out anything? What I've tried so far is trying to block on the input stream provided by the Http request and hoping it would throw an exception if the client drop the conntection, but that does not work, the input stream just return -1 to any read operation no matter if the client is still connected or not. Cheers Andrea -- View this message in context: http://www.nabble.com/How-to-check-if-the-client-dropped-the-connection-tp25641481p25658980.html Sent from the Tomcat - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: How to check if the client dropped the connection
Markus Meyer wrote: I'm not saying you should store the whole map all at once. My approach was to dynamically cache requests that the client may want to make in advance. An easy example would be if a client makes a request for the city center, you create the map for the city center plus the suburbs around it and store it somewhere, then return the city center. If the user then moves around a bit to see the suburbs, you already have the whole map cached and just need to return it, no need to do any further calculation. Sorry, I've lost you there. How is drawing a bigger image going to solve the problem, which in the end is both a CPU waste but also an OOM due to too many images being generated at the same time because of the user zooming in and out fast (most of them are actually not wanted anymore by the client which in the meantime will drop the connection). If anything your suggestion seems to make the client wait longer and the server OOM faster. Markus Meyer wrote: If you then also compress the image on the fly while you are reading it from disk (or from some memory cache), you will start writing to the output stream very soon (also detecting the dropped connection very soon) and the servlet will not need much RAM. Of course this does not work if you just use Java's built-in PNG encoder. Obviously, caching always comes with the price that you will have the occassional cache miss :-) That is, this does not work for every request but may decrease load and RAM usage a lot for typical use cases. WMS and tile systems are related, but they don't work the same way, I cited tiling because it's the thing people know the most given the Google maps popularity. A desktop WMS client won't use any pre-defined tile structure, each request will be different in terms of layer requested, zoom level, and area. The potential for caching is very, very low. The tile system are on the other side setup to make caching possible and efficient by imposing structure on the requests, but what I'm dealing with here is pure WMS. What I'm talking about here are the industry standard solutions for WMS map rendering. We can discuss this at lenght and we could come out with some interesting new way that was not tried before in the field. But in the meatime I would really appreciate if anybody could answer my first question: how does one detect the client connection has been dropped? Is there any way? Does anybody know? Markus Meyer wrote: In your OP you write: Unfortunately in the meantime the older requests are still running, drawing a map takes time and a lot of memory, for example the above request, which is a small one btw, allocates a BufferedImage of 700KB. This indicates that you (1) seem to not use any caching (drawing a map takes time - with caching the map would already have been drawn) and (2) you use BufferedImage which of course does not allow you to PNG-encode on the fly. Both problems would be solved with the above suggestion. The rendering subsystem actually takes a Graphics2D. If you can suggest ways to draw lines, points and polygons on a raster image that is not memory bound (like a buffered image) and has no sewing effects (like tiles, that do break labelling, long story, don't get me started on this) I'm all ears. Cheers Andrea -- View this message in context: http://www.nabble.com/How-to-check-if-the-client-dropped-the-connection-tp25641481p25659184.html Sent from the Tomcat - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
How to check if the client dropped the connection
Hi, I'm working on the development of an open source application, GeoServer, implementing the Web Map Service specification. The specification allows a client to request maps using simple GET requests like: http://sigma.openplans.org:8080/geoserver/wms?WIDTH=431SRS=EPSG%3A4326LAYERS=tiger-nyHEIGHT=550STYLES=FORMAT=image%2FpngSERVICE=WMSVERSION=1.1.1REQUEST=GetMapEXCEPTIONS=application%2Fvnd.ogc.se_inimageBBOX=-74.01697805908182,40.69808217724622,-73.99567744140603,40.72526393994153 and the client gets back a PNG with a map of the request area. No asynchronism is allowed, the protocol is standardized (http://portal.opengeospatial.org/files/?artifact_id=1058) and I have no controls over the clients (there are tens of them around, both open source and proprietary) which are free to make as many request as they like, in whatever order the like. By spec we're forced to use a plain request and response approach, but we're experiencing a problem with clients making lots of request as the user zooms/pans around: basically a request is made, but the user keeps on moving, the client drops the older requests (closing the connection in face of the server) and makes others. Unfortunately in the meantime the older requests are still running, drawing a map takes time and a lot of memory, for example the above request, which is a small one btw, allocates a BufferedImage of 700KB. The memory is consumed up until the image is encoded out to the stream, which is also the moment we finally figure out the client dropped the connection (since writing to the servlet output stream fails). This is very sub-optimal. Servers like Apache with cgi do kill the cgi process the moment the connection is dropped, significantly reducing the server load both in terms of CPU and memory consumption. Is there any way to check if the client connection is still open using only the standard servlet API? If not, is there any Tomcat specific approach that might work instead? If there is no solution that can be applied at the general servlet api level, do you know of any Tomcat specific approach one could use? e.g., casting the HttpServletResponse to some Tomcat specific class and get some connection information status there? Cheers Andrea -- View this message in context: http://www.nabble.com/How-to-check-if-the-client-dropped-the-connection-tp25641481p25641481.html Sent from the Tomcat - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: How to check if the client dropped the connection
jasonb wrote: Hi Andrea. When the client disconnects, and your servlet tries to write to the output stream, Tomcat will throw a ClientAbortException (you may have already seen this): http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/connector/ClientAbortException.html Tomcat appears to only throw this exception when you either write some bytes to the output stream or when you flush the output stream, and the client already closed its end of the connection. It appears that you could periodically try flushing the output stream and see if doing so throws this exception. You can flush after writing any number of bytes, including zero bytes. The first time you call flush, it will send the HTTP response headers to the client, so you would need to first set the headers before flushing. That sounds difficult for you to do because you're writing an image, and one of the headers would be Content-Length, which you probably don't know until your image is generated. We actually don't send the content length out, we used chunked transfer instead (that is, stream out the result of the png compression as made by JAI Image I/O) but unfortunately we cannot do that either, as the protocols mandates that any error occurring during rendering be returned as XML. So I actually know the final content type only when the image is fully rendered, which is when I start writing out bytes anyways. Cheers Andrea -- View this message in context: http://www.nabble.com/How-to-check-if-the-client-dropped-the-connection-tp25641481p25651470.html Sent from the Tomcat - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: How to check if the client dropped the connection
Markus Meyer wrote: Jason Brittain schrieb: The first time you call flush, it will send the HTTP response headers to the client, so you would need to first set the headers before flushing. That sounds difficult for you to do because you're writing an image, and one of the headers would be Content-Length, which you probably don't know until your image is generated. Actually, Content-Length is optional as per the HTTP-1.1 spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html However, my take on the OP is that a better optimization strategy in this case would be to just cache a larger image on the server rather than generating every image on-demand. That is, when the user is moving around in the image, the server, on the first request, would calculate the image for a much larger portion of the map than requested and stores it on disk in temporary storage (or in some cache area in RAM, if feasible, after all RAM is cheap these days and 64-bit machines can have lots of RAM). Storage of the images would not be done all at once but in tiles. When then user then moves around in the client, the requests just reads the tiles of the created image from disk, puts them together and clips the borders, then compresses the image and sends it to the client. It is possible that PNG even has some support for compressing parts of an image so the tiles itself could be already stored in compressed format, but it's been a while since I read the PNG spec last time. The same could be done for zooming by storing images in a pyramidal structure, like it is done in pattern recognition. While the user is moving, a background thread associated with the client could try to anticipate where the user is likely to be moving to and calculate the given tiles in advance. Actually, this sounds like an interesting project for several Ph.D. theses... Well, something like that has actually been done already, it's called tile caching, and works under the restrictive conditions that you can force the client to make requests in predetermined sizes and tiles. As for applying this to the general case, I invite you to have a look at how big the raster surface is and how much space is required to actually store on the disk a full map (only _one_ map, some GeoServer installs do serve 500-1000 different layers) here: http://geowebcache.org/trac/wiki/resources (the site is describing the tile cache companion to GeoServer, called GeoWebCache) So, it is somewhat doable, but only for a few backgrond layers that do not change that often (once a month may be ok if you don't need to zoom in too much). Cheers Andrea -- View this message in context: http://www.nabble.com/How-to-check-if-the-client-dropped-the-connection-tp25641481p25651562.html Sent from the Tomcat - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Any way to check the client abruptly close the connection?
Johnny Kewl wrote: This is an interesting question, and I'm going to guess... If you in a JSP page, I dont think the error can be trapped. If you in a servlet, yes I think a try catch will detect it, but only if you actually write something. Which I can't do. The WMS is an international standard, I cannot bend it to my will, since the point of the application is to be fully conformant to it. This is a pity, I mean, the webapp container should have a way to check the socket is gone bye bye without writing on it, no? Cheers Andrea -- View this message in context: http://www.nabble.com/Any-way-to-check-the-client-abruptly-close-the-connection--tf4043946.html#a11496790 Sent from the Tomcat - User mailing list archive at Nabble.com. - To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Any way to check the client abruptly close the connection?
Hi, I'm fighting a relatively nasty issue. I've implemented a WMS service (Web Map Server), which basically returns a geographic map in response to a request stating which data to use, which area to display, which style to apply to the map, and so on. The main trouble is that building the map can take anywhere from 100ms to minutes, depending on how much data is needed, and during the map building time the output stream is not touched (the map is drawn on a buffered image, which is encoded to png/gif/jpeg only when completely drawn). It happens quite often that the client closes the connection because the map is taking too much time to be generated, and I would like to be informed about this right away to avoid wasting precious resources. Is there any way to know? Cheers Andrea -- View this message in context: http://www.nabble.com/Any-way-to-check-the-client-abruptly-close-the-connection--tf4043946.html#a11487168 Sent from the Tomcat - User mailing list archive at Nabble.com. - To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]