https://issues.apache.org/bugzilla/show_bug.cgi?id=50495
Summary: Comet connector needs ability to access the client send queue. Product: Tomcat 7 Version: 7.0.5 Platform: PC OS/Version: All Status: NEW Severity: blocker Priority: P2 Component: Connectors AssignedTo: dev@tomcat.apache.org ReportedBy: gober...@msn.com I use NIO HTTP Tomcat connector org.apache.coyote.Http11NioProtocol to implement Comet streaming to browsers and mobile devices. The application opens 'primary' persistent Comet connection to receive data from the server. Server sends data to the client periodically. It will be possible that one of the clients is "slow reader" for various reasons. If I call PrintWriter.print("message") to send data to such client, the message will be queued internally by the Tomcat "Comet Processor". If message flow is heavy, the client message queues may become large and Tomcat can run out of memory. I was able to duplicate this quite easily by sending messages in a loop. It will be critical to address these issues for any "production quality" application. I would like to request 2 enhancements to address this: 1) I would like to somehow "compress" the pending client's queue. Messages I send are financial market data messages. So if I send message for stock IBM and the message is queued, then when a new message for IBM is generated, I should be able to detect that there is a message in the queue pending to be sent and just replace content of the one already pending instead of queuing a new one. 2) If queue for a client reaches a high water mark, I should be able to detect it, disconnect the client and delete the queue. This is how data is sent now with Tomcat Comet: PrintWriter out = response.getWriter(); out.print("my message"); This is how I would prefer it to work. This is very rough idea. // Comet PrintWriter will be exposed: CometPrintWriter out = (CometPrintWriter)response.getWriter(); // detect queue size and disconnect if necessary. int queueSize = out.getQueue().size() // get cached message for the stock symbol ICometMessage existingMessageForTheSymbol = ... if (existingMessageForTheSymbol == null) { ICometMessage newMessage = new MyMessage(...) out.addMessage(newMessage); // cache the newMessage in a Map. } else { if (!existingMessageForTheSymbol.replaceMessage(...)) { // message is already sent. need to create a new one: ICometMessage newMessage = new MyMessage(...) out.addMessage(newMessage); // cache the newMessage in a Map. } } // this interface would be a part of Tomcat Comet interface ICometMessage { // called by Tomcat comet before message is sent. void beforeMessageSent(); // called by Tomcat comet after message is sent. void afterMessageSent(); } class MyMessage implements ICometMessage { ReentrantLock lock = ...; boolean messageSent; public void beforeMessageSent() { lock.lock(); messageSent = true; } public void afterMessageSent() { lock.unlock(); } public boolean replaceMessage(...) { lock.lock(); if (messageSent) { lock.unlock(); return false; } // replace message data. lock.unlock(); return true; } } -- Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org