Re: nio connector configuration

2009-02-19 Thread Peter Warren
Sorry to bump this thread.  I'm willing to pay for some assistance if
anyone's interested in helping.  I'm trying to figure out 2 problems
when running my system under a light-moderate load test:

1) why do my comet timeout events not get generated on time (supposed
to be every 50 seconds, averaging 56s, with many refused connections
skewing the average down, max 85s)?

2) why is tomcat refusing connections under what seems to be a reasonable load?

I'm happy to do more legwork on my own -- just looking for some
pointers here.  Can anyone help me out?

Looking at JConsole, 2 items that look suspicious: 1) blocked
http-acceptor threads, and 2) block-poller and client-poller threads
that show a high number of blocks (see below).  Also, the non-comet
http requests are returning quickly, averaging ~150ms, so it seems to
be only my comet requests that are having issues.

Running a load test with 600 total client threads averaging 14
requests/sec.  300 threads making normal http requests, 300 threads
making comet requests that wait 50 seconds for a server timeout.

Tomcat 6.0.18 on Windows XP.

Connector port=80 protocol=org.apache.coyote.http11.Http11NioProtocol
maxThreads=1000
acceptorThreadCount=5
acceptorThreadPriority=10
pollerThreadCount=5
pollerThreadPriority=10
redirectPort=8443
enableLookups=false /

after 1/2 hour running:

normal http requests:
2 samples, averaging 150 ms, ~.5% error

comet requests:
1 samples, averaging 56s, ~3.5% error

Information from JConsole:

CPU avg: 5-10%
threads: stable @ ~300
memory: stable @ ~130MB

Thread status from JConsole of the http-acceptor, block-poller, and
client-poller threads:

Name: http-80-Acceptor-0
State: BLOCKED on java.lang.obj...@17a82f1 owned by: http-80-Acceptor-4
Total blocked: 132  Total waited: 0

Stack trace:
sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:1198)
java.lang.Thread.run(Unknown Source)

-

Name: http-80-Acceptor-1
State: BLOCKED on java.lang.obj...@17a82f1 owned by: http-80-Acceptor-4
Total blocked: 129  Total waited: 0

Stack trace:
sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:1198)
java.lang.Thread.run(Unknown Source)

-

Name: http-80-Acceptor-2
State: BLOCKED on java.lang.obj...@17a82f1 owned by: http-80-Acceptor-4
Total blocked: 122  Total waited: 0

Stack trace:
sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:1198)
java.lang.Thread.run(Unknown Source)

-

Name: http-80-Acceptor-3
State: BLOCKED on java.lang.obj...@17a82f1 owned by: http-80-Acceptor-0
Total blocked: 166  Total waited: 0

Stack trace:
sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:1198)
java.lang.Thread.run(Unknown Source)

-

Name: http-80-Acceptor-4
State: BLOCKED on java.lang.obj...@17a82f1 owned by: http-80-Acceptor-0
Total blocked: 133  Total waited: 0

Stack trace:
sun.nio.ch.ServerSocketChannelImpl.accept(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:1198)
java.lang.Thread.run(Unknown Source)

-

Name: http-80-ClientPoller
State: RUNNABLE
Total blocked: 17,950  Total waited: 5

Stack trace:
sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source)
sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source)
sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
   - locked sun.nio.ch.uti...@f7b8fc
   - locked java.util.collections$unmodifiable...@195afdb
   - locked sun.nio.ch.windowsselectori...@c56236
sun.nio.ch.SelectorImpl.select(Unknown Source)
org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:1473)
java.lang.Thread.run(Unknown Source)

-

Name: NioBlockingSelector.BlockPoller-1
State: RUNNABLE
Total blocked: 10,645  Total waited: 0

Stack trace:
sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(Unknown Source)
sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(Unknown Source)
sun.nio.ch.WindowsSelectorImpl.doSelect(Unknown Source)
sun.nio.ch.SelectorImpl.lockAndDoSelect(Unknown Source)
   - locked sun.nio.ch.uti...@b2ee9a
   - locked java.util.collections$unmodifiable...@14eda77
   - locked sun.nio.ch.windowsselectori...@1e8bb4c
sun.nio.ch.SelectorImpl.select(Unknown Source)
org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:305)

Thanks for any help,
Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: nio connector configuration

2009-02-13 Thread Peter Warren
I'm trying to figure out how best to configure nio so that my comet
timeout events get generated in a timely manner.  I have the comet
events set to generate a timeout every 50 seconds.  Works fine with
few users.  Under a moderate but reasonable load the timeout gets
generated on average every 113 seconds.  My configuration tweaks
haven't yielded any noticeable changes (see below).

Test results...

Background:
- using JMeter
- 300 threads executing normal http requests, averaging ~9.8 requests/second.
- 300 threads executing comet requests that simply wait for the server
to close the connection every 50 seconds, averaging ~2.6
requests/second.
- server is ubuntu 8.10 running tomcat 6.0.18.
- server is not cpu constrained, averaging about 8-12% cpu
- server doesn't seem to be memory constrained.  top shows 80% of
memory after hours of test (machine has 512MB physical memory and
tomcat has a max heap set to 384MB)
- network latency isn't a problem

I ran 2 tests with different configurations for the nio connector: 1
test with bare-bones settings, and 1 test with everything that seemed
like it might make a difference.

Connector port=80 protocol=org.apache.coyote.http11.Http11NioProtocol
redirectPort=8443
enableLookups=false /

Ran for 3+ hours.
8-12% cpu.
12.4 requests/second.
comet requests: average response time 112 secs, min 21 secs, max 179 secs

Connector port=80 protocol=org.apache.coyote.http11.Http11NioProtocol
maxThreads=1000
minSpareThreads=200
acceptorThreadCount=20
acceptorThreadPriority=10
pollerThreadCount=20
pollerThreadPriority=10
redirectPort=8443
enableLookups=false /

Ran for 1 1/2 hours.
8-12% cpu.
12.2 requests/second.
comet requests: average response time 113 secs, min 50 secs, max 133 secs

So how can I get my comet timeouts generated at close to 50 secs under load?

I thought maybe the poller thread priority was too low (does the
poller thread generate the timeouts?), but setting its priority to max
didn't change anything.

Just to make sure I wasn't doing anything dumb in my client code, I
replaced my event() method with the one below and still got the same
disparity in comet timeouts, ranging from 50 to 120 secs:

public void event(CometEvent event) throws IOException, ServletException {
HttpServletRequest request = event.getHttpServletRequest();
if (event.getEventType() == CometEvent.EventType.BEGIN) {
event.setTimeout(5);
} else if (event.getEventType() == CometEvent.EventType.ERROR) {
event.close();
} else if (event.getEventType() == CometEvent.EventType.END) {
event.close();
} else if (event.getEventType() == CometEvent.EventType.READ) {
InputStream is = request.getInputStream();
byte[] buf = new byte[512];
do {
is.read(buf); // can throw an IOException
} while (is.available()  0);
}
}

I just checked the priority of the thread issuing the comet timeout
event and its priority is 5.  I have both the acceptor and poller
thread priorities set to 10.  How can I bump up the priority of the
thread that issues the timeout events (in this case named
http-80-exec-1)?

Thanks for any ideas,
Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



comet end vs. client_disconnect

2009-02-11 Thread Peter Warren
How do I distinguish between a comet END event generated due to a
client disconnect and an end event generated for some other reason?

I'm using tomcat 6.0.18 with the nio connector.  On both windows xp
sp3 and ubuntu 8.10, I'm seeing END events generated when a client
disconnects and for other situations.  I never receive error events
with a subtype of CLIENT_DISCONNECT, which is what I was expecting
when a client disconnects.

In the aio docs, I read:
End will also be called when data is available and the end of file is
reached on the request input (this usually indicates the client has
pipelined a request).

So END events get generated on a client disconnect but may also get
generated for pipelined requests.  So how can I tell definitively if a
client disconnects?

I also read:
note: some of these events require usage of the
org.apache.catalina.valves.CometConnectionManagerValve

so I enabled the CometConnectionManagerValve, but still I don't
receive error events with a CLIENT_DISCONNECT subtype.

I've got stack traces for the 2 situations I encounter that generate
end events.

This partial stack is from a client disconnect that generates an END event:
Http11NioProcessor.event(SocketStatus) line: 750
Http11NioProtocol$Http11ConnectionHandler.event(NioChannel,
SocketStatus) line: 653
NioEndpoint$SocketProcessor.run() line: 2081

This partial stack is from something other than a client disconnect
(maybe a pipelined request?) that generates an END event:
Http11NioProcessor.process(NioChannel) line: 880
Http11NioProtocol$Http11ConnectionHandler.process(NioChannel) line: 719 
NioEndpoint$SocketProcessor.run() line: 2081

Note that the traces diverge at NioEndpoint$SocketProcessor.run()
line: 2081 due to the value of NioEndpoint$SocketProcessor.status,
which is null in the second case.

Is there a configuration issue that I can remedy to start receiving
error events with subtype CLIENT_DISCONNECT?  Barring that, is there
some flag in the CometEvent or some object accessible from the
CometEvent that I can use to tell if an END event was generated due to
a client disconnect?

Thanks,
Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: comet end vs. client_disconnect

2009-02-11 Thread Peter Warren
 CLIENT_DISCONNECT is only used a subtype of ERROR
 and that happens when the socket is closed from the client side

When a client disconnects (i.e. socket is closed from the client
side), I see an END event on both Windows and Ubuntu.  I expected an
ERROR event with a subtype of CLIENT_DISCONNECT, but I receive no
ERROR events of any kind.  Should I be receiving the ERROR event in
addition to or instead of the END event?

Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



nio connector configuration

2009-02-11 Thread Peter Warren
Looking for nio configuration tips for 6.0.18...

I have an ajax app that uses a single socket connection for sending
standard http requests and receiving responses, and another socket
connection to listen via comet for messages pushed out by the server.
A comet timeout is generated every 50 seconds, and the server then
closes the client connection.  The client immediately reconnects.
This heartbeat lets me know the client is still alive.

In load testing with JMeter, I find that when running somewhere
between 100  200 threads (1/2 making regular http requests and 1/2
making comet listen requests that connect and then wait until the
server closes the connection) the comet timeout events get generated
more and more slowly.  When they should be generated every 50 seconds,
after only a little over a minute into the load test, the timeouts
slow to sometimes over 60 seconds.  When running 100 threads, the
system works fine with the timeouts occurring less than every 60
seconds indefinitely.

I'm not much of a tomcat administrator and am trying to figure out how
to best to tune it for my app.  This is what my connector config looks
like now.  Basically I'm throwing the kitchen sink at it, and then
planning on fine-tuning it once I find something that makes a
difference.

Connector port=80 protocol=org.apache.coyote.http11.Http11NioProtocol
maxThreads=1000
acceptCount=18192
acceptorThreadCount=2
acceptorThreadPriority=10
pollerThreadCount=2
pollerThreadPriority=10
maxKeepAliveRequests=-1

command-line-options=-Dorg.apache.tomcat.util.net.NioSelectorShared=false
selectorPool.maxSelectors=500
redirectPort=8443
enableLookups=false /

A couple notes:
the acceptorThreadPriority and pollerThreadPriority are set using ints
because I get the following warnings in the catalina log when trying
to use the documented notation:
WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting
property 'pollerThreadPriority' to 'java.lang.Thread#MAX_PRIORITY' did
not find a matching property.

I also get the warning when trying to use keepAliveTimeout.  Is this
property available for the nio connector?
WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting
property 'keepAliveTimeout' to '12' did not find a matching
property.

I also get the warning when trying to use command-line-options, or am
I supposed to really be setting this property on the command line?
WARNING: [SetAllPropertiesRule]{Server/Service/Connector} Setting
property 'command-line-options' to
'-Dorg.apache.tomcat.util.net.NioSelectorShared=false' did not find a
matching property.

Thanks for any tips,
Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: nio connector configuration

2009-02-11 Thread Peter Warren
Thanks for the tips.  Very helpful.

 I also get the warning when trying to use keepAliveTimeout.
 Is this property available for the nio connector?

 No; it's only listed under the older connector (the one labeled Standard 
 Implementation that then somewhat ambiguously refers to HTTP).

I suspected as much, but got confused when I used the acceptCount
property and tomcat didn't complain.  acceptCount is only listed under
the standard implementation as well, so I expected a warning.

 '-Dorg.apache.tomcat.util.net.NioSelectorShared=false' did not find a
 matching property.

 Works for me (at least I don't get any error message) on 6.0.18 running with 
 JDK 6u12 on a Vista 64 box; how are you setting the above property, and what 
 are your running on?

I was setting it as a property in the connector config.  Maybe that
was silly of me, but I thought maybe all the properties were localized
in the connector.  I just tried it as a command-line option and it
seemed to work.

Interesting side note, with
-Dorg.apache.tomcat.util.net.NioSelectorShared=false set and
selectorPool.maxSelectors=500.  My server code starts generating
comet END events after about 30 threads start and only about 10
seconds into the test.

Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: comet loop after webapp re-start

2009-02-05 Thread Peter Warren
Thanks for the pointer.  That bug does look related, as does this one:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6403933 -- fixed
against java 7.

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



comet loop after webapp re-start

2009-02-04 Thread Peter Warren
I'm running tomcat 6.0.18 on Ubuntu 8.10.  I have a comet application
that maintains an open connection with tomcat.  If I re-start my
webapp and then close the client connection, tomcat goes into a loop
and chews up all cpu.  This server is not live and only has my single
client.

The ClientPoller thread consumes most of the cpu running through the
following stack over and over.

Daemon Thread [http-80-ClientPoller] (Suspended (breakpoint at line
654 in ThreadPoolExecutor))
ThreadPoolExecutor.execute(Runnable) line: 654  
NioEndpoint.processSocket(NioChannel, SocketStatus, boolean) line: 1161 
NioEndpoint.processSocket(NioChannel, SocketStatus) line: 1148  
NioEndpoint$Poller.processKey(SelectionKey,
NioEndpoint$KeyAttachment) line: 1555
NioEndpoint$Poller.run() line: 1508 
Thread.run() line: 619  

This is not a problem with my CometProcessor not handling the comet
events; the END event when the client connection is closed is never
delivered to my CometProcessor, understandably since I just re-started
the webapp and there is now a new CometProcessor instance.

I believe what is happening is that the NIO connector is trying to
deliver the END event to a CometProcessor that no longer exists and
just keeps trying.  Should the NIO connector recognize that the event
is undeliverable and give up?  Or is there something I need to do in
webapp shutdown code to tell the NIO processor to disregard any open
connections?

The workaround is to always re-start the tomcat instead of just the
webapp.  This is possible for me since my server is only serving a
single webapp.

Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: comet loop after webapp re-start

2009-02-04 Thread Peter Warren
 What JVM are you using?  The stack trace doesn't look like anything that a 
 HotSpot JVM would produce.

It's Sun Java 1.6.0_10-b33.  I grabbed the trace from my eclipse
debugger.  And I see the loop when running both with and without vm
debug flags.

Peter

-
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



Re: comet end event

2008-01-29 Thread Peter Warren
Could you indulge me and try the client with the sleep?

I see the end event when there's a break/delay between sending a chunk
and sending the last chunk.  It is legal http to send the last chunk
separately from preceding chunks, isn't it?

 getting a -1 on a inputstream.read is normal (even for a regular servlet).

The read error indicates slightly more: that
inputstream.isAvailable() is 0 and that inputstream.read() returns
-1.  Do I understand correctly in thinking that this -1 can indicate
two different situations: 1) the client sent a last chunk; or 2) the
client socket closed while the server was reading?

If the above is true, it might be nice to have a way to disambiguate
the two situations.  Also, documentation-wise, it might be nice to
comment the servlet code in
http://tomcat.apache.org/tomcat-6.0-doc/aio.html to indicate that the
-1 can occur on a last chunk as well as a read error.  As a new comet
user, I incorrectly took your sample code block (in the aio doc page)
below to mean that a -1 always indicated some kind of error:

} else if (n  0) {
  error(event, request, response);
  return;
}

Thanks,
Peter

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet end event

2008-01-29 Thread Peter Warren
  Could you indulge me and try the client with the sleep?
 
 just did, worked exactly as before.
 event: BEGIN, subtype: null
 event: READ, subtype: null
 Read 10 bytes: comet test for session: A01334D0AC22505DCD4B323820963FEC
 read error
 event: ERROR, subtype: TIMEOUT

Hmm, not sure where to go from here then.  Here's my output:

Jan 29, 2008 4:36:23 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 1173 ms
event: BEGIN, subtype: null
event: READ, subtype: null
Read 10 bytes: comet test for session: CAF116EB9DF8BB1C5DD3170FC70F2394
event: END, subtype: null

 If you are unsure if you have messed up Tomcat binaries, then I would test 
 this one
 http://people.apache.org/~fhanik/tomcat/tomcat-5.5/v5.5.26/bin/

I don't think it's bad binaries 'cause I've rebuilt a number of times,
but I'm happy to give new binaries a try.  You're pointing to tomcat
5.5 binaries though -- I thought comet was a 6.0 feature.  Should I
try the 5.5 binaries anyway?

 yes, we are very aware that the sample code is not the best for getting
 started, we are looking to replace it, but it takes time and resources.

I didn't mean to be critical -- merely pointing out an area of
confusion for me.  In fact, I thought the sample code was reasonably
sufficient for me to get up and running.  My main issues were getting
the client http chunking working properly.

 contributions always welcome!

I'm pretty sure you don't want me writing the sample code! :)  I'm
still learning here, but I hope that our dialog is a contribution of
sorts.  As I mentioned before, my comet app is working fine using
non-chunked httpurlconnections.  This end event issue is not a
roadblock for me -- I'm pursuing it to help tomcat and tomcat users,
and satisfy my own curiosity of course. :)  Hopefully others will
learn from my misunderstandings, code snippets, etc.

Peter

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet end event

2008-01-28 Thread Peter Warren
Is the read error expected behavior?  I guess I didn't expect the
comet processor to send me a read event on a last chunk since there's
nothing to be read.  I thought either a read error or an end event
after a last chunk indicated a problem.  If the read error is ok,
then...

Did you try the client with the 50 ms sleep?  The client code has a
commented block that says: uncomment sleep to get END event instead of
read error.  Adding the sleep generates the end event for me.

Also, did you try with your cometgui client?  As I mentioned,
submitting a chunk and then separately submitting an end chunk
generates an end event for me.  If I send the two chunks together, I
get the read error.

Peter

On Jan 28, 2008 1:37 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 works just dandy, the timeout happens after quite some time of just waiting

 Jan 28, 2008 2:33:31 PM org.apache.coyote.http11.Http11NioProtocol start
 INFO: Starting Coyote HTTP/1.1 on http-8080
 Jan 28, 2008 2:33:31 PM org.apache.catalina.startup.Catalina start
 INFO: Server startup in 1005 ms
 event: BEGIN, subtype: null
 event: READ, subtype: null
 Read 10 bytes: comet test for session: D4BC1A6D7AC7F30C1A475FB7FFB2B4DB
 read error
 event: ERROR, subtype: TIMEOUT

 If you are unsure if you have messed up Tomcat binaries, then I would
 test this one
 http://people.apache.org/~fhanik/tomcat/tomcat-5.5/v5.5.26/bin/

 these are not an official version, but you can test it out and see how
 your test works

 Filip


 Peter Warren wrote:
  I put up a war file at: http://www.nomad.org/comet_test.war.
 
  It includes the webapp, source for the comet servlet  client, and the
  server.xml file.  Let me know if I missed anything.
 
  As I mentioned before, I've also used your cometgui.jar client and see
  the end event generated when using it as well.  If I submit a chunk
  and the last chunk (0crlfcrlf) together, I see a read error on the
  server.  If I submit a chunk and then submit the last chunk in two
  separate submissions, I see an end event on the server.
 
  Peter
 
  On Jan 24, 2008 12:44 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 
  even with your code, I wasn't able to replicate what you were seeing.
  what I would need to see what's going on for you:
 
  1. a war file with your comet server, and source code
  2. a test client
  3. your server.xml
 
  Filip
 
 
 

  -
  To start a new topic, e-mail: users@tomcat.apache.org
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 


 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet end event

2008-01-22 Thread Peter Warren
$Worker.run(ThreadPoolExecutor
.java:907)
at java.lang.Thread.run(Thread.java:619)
event: ERROR, subtype: null


Code for LastChunkTest:
===
package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.URL;

public class LastChunkTest {

private static final String ENCODING = ISO-8859-1;

private static final String DELIMITER = \r\n;

private URL url;

private InputStream inputStream;

private OutputStream outputStream;

private Socket socket;

public static void main(String[] args) throws Exception {
LastChunkTest test = new LastChunkTest();
test.test();
}

private void test() throws Exception {
url = new URL(http://www.seekspeak.com/CometTest;);
initConnection();
sendHeaders();
send(comet test);
// uncomment sleep to get END event instead of read error
//try {
//Thread.sleep(50);
//} catch (InterruptedException ie) {
//// do nothing
//}
sendLastChunk();
// block on read to keep app alive - server never sends response
inputStream.read();
}

private void initConnection() throws IOException {
int port = url.getPort();
port = (port  0) ? url.getDefaultPort() : port;
try {
socket = new Socket(url.getHost(), port);
socket.setKeepAlive(true);
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (NoRouteToHostException nrthe) {
System.out.println(host:  + url.getHost());
nrthe.printStackTrace();
}
}

private void sendHeaders() throws IOException {
String path = url.getPath();
StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append(POST  + path +  HTTP/1.1 + DELIMITER);
outputBuffer.append(Host:  + url.getHost() + DELIMITER);
outputBuffer.append(User-Agent: CometTest + DELIMITER);
outputBuffer.append(Connection: keep-alive + DELIMITER);
outputBuffer.append(Content-Type: text/plain + DELIMITER);
outputBuffer.append(Transfer-Encoding: chunked + DELIMITER);
outputBuffer.append(DELIMITER);
byte[] outputBytes = outputBuffer.toString().getBytes(ENCODING);
outputStream.write(outputBytes);
outputStream.flush();
}

private void send(String chunkData) throws IOException {
byte[] chunkBytes = chunkData.getBytes(ENCODING);
String hexChunkLength = Integer.toHexString(chunkBytes.length);
StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append(hexChunkLength);
outputBuffer.append(DELIMITER);
outputBuffer.append(chunkData);
outputBuffer.append(DELIMITER);
byte[] outputBytes = outputBuffer.toString().getBytes(ENCODING);
outputStream.write(outputBytes);
outputStream.flush();
}

private void sendLastChunk() throws IOException {
byte[] outputBytes = new String(0 + DELIMITER).getBytes(ENCODING);
outputStream.write(outputBytes);
outputStream.flush();
}
}


On Jan 22, 2008 9:07 AM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 I still don't get the END event, however, thanks for pointing it out,
 you did find a regression bug about the timeout

 http://svn.apache.org/viewvc?view=revrevision=614249

 I've added the patch above to the proposal list for 6.0.x to fix the
 timeout issue

 Filip


 Peter Warren wrote:
  as I  mentioned, the last chunk doesn't generate an END event, I tried
  it locally. of course against 6.0.x trunk.
 
 
  I played around a bit because I was definitely getting an END event
  and found: Sending 0crlf does not generate and END event.  However
  sending 0crlfcrlf, which is what HttpURLConnection does, does generate
  an END (or sometimes a read error - see below...)  Looking at the http
  spec, it seems like 0crlfcrlf is actually the proper way to terminate
  the chunk body:
 
 Chunked-Body   = *chunk
  last-chunk
  trailer
  CRLF
 
 last-chunk = 1*(0) [ chunk-extension ] CRLF
 
  Am I reading that correctly?
 
  Note about END and read error:
  When running both the client and the server locally (i.e. little
  latency), sending 0crlfcrlf would sometimes generate a read error
  (i.e. inputStream.isAvailable()  0 would be true and then number of
  bytes read would be  0) and sometimes an END event.
 
  I tried with both sockets and HttpURLConnection and saw similar
  behavior.  However when using HttpURLConnection I could add a delay of
  50 millis. and guarantee that I always got an end event (see code
  below).
 
  I am using the latest 6.0.x trunk updated locally today.
 
  Peter
 
  CLIENT CODE

Re: comet end event

2008-01-22 Thread Peter Warren
);
 outputStream.flush();
 }

 private void sendLastChunk() throws IOException {
 byte[] outputBytes = new String(0 +
 DELIMITER+DELIMITER).getBytes(ENCODING);
 outputStream.write(outputBytes);
 outputStream.flush();
 }
 }


 Peter Warren wrote:
  Just to make sure that I wasn't crazy, I did some more tests,
  including using your cometgui.jar.  My results still show both read
  errors and END events.  Is it possible that it's a platform issue?
  I'm running Windows XP Pro SP2.  As I mentioned before I'm using the
  tomcat 6.0.x trunk as of 21-01-2008.  Also, I re-started tomcat in
  between all tests to make sure there weren't stray bytes hanging
  around somewhere.  My server code is the same as shown previously in
  this thread.
 
  Peter
 
  Here are my results:
 
  1) Running LastChunkTest (code below) with last chunk of 0crlfcrlf,
  server shows:
 
  event: BEGIN, subtype: null
  event: READ, subtype: null
  Read 10 bytes: comet test for session: 627378C9DEE2817A93EBAC190DE47599
  read error
 
  2) Running LastChunkTest with last chunk of 0crlfcrlf and a 50 ms
  sleep before sending last chunk, server shows:
 
  event: BEGIN, subtype: null
  event: READ, subtype: null
  Read 10 bytes: comet test for session: A00EFFC9A9FE8CBF1833D204EF00667C
  event: END, subtype: null
 
  3) Running LastChunkTest with a last chunk of 0crlf, server shows:
 
  event: BEGIN, subtype: null
  event: READ, subtype: null
  Read 10 bytes: comet test for session: DD41C198E3D5CD6E7D73FC0D7B37E86F
 
  4) Running cometgui.jar with 0crlfcrlf:
 
  client sends (without the dashes):



 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet end event

2008-01-21 Thread Peter Warren
First off, thanks for your responses.  The contributors to this list
are extremely responsive, patient, and helpful, and I really
appreciate it!

Hmm, in your test case did you set the HttpURLConnection to use
chunked transfers (setChunkedStreamingMode(...))?  I find if I use
chunked transfers, the HttpURLConnection sends a last chunk message
upon reading input from the server, which generates a comet END event
on the server.  If I don't use chunked transfers, no END event is
generated because no last chunk is sent by the client.

Which brings up an option I never considered: will a comet servlet
function properly with non-chunked transfer (i.e. no transfer-coding
header)?  It seems to.

Lastly, I'm still a little confused about requiring the comet event to
be closed on an END event.  Doesn't this mean that tomcat comet can't
handle pipelined requests?  If a client sends 2 pipelined requests, it
will send a last chunk to indicate the end of the first request.
This last chunk will generate an END event on the server, which then
requires the connection to be closed.  After the comet event is closed
the server cannot send a response to the client.

The END event docs indicate that pipelined request will generate an
END event: ...End will also be called when data is available and the
end of file is reached on the request input (this usually indicates
the client has pipelined a request).

Thanks,
Peter

On Jan 20, 2008 8:15 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:

 now I get it. I just ran through a test case, and an END event was not
 thrown just because there was an end chunk.
 the response is very much still open at that point


 Filip

 Peter Warren wrote:
  What java.net.HttpURLConnection has to do with Tomcat and comet is
  that HttpURLConnection is Java's implementation of an http client and
  will likely be used by people developing comet apps for Tomcat.  In my
  case, I want to use it because I can't use raw sockets on my applet
  client due to permission problems when trying to use sockets behind a
  proxy.
 
  I understand that asynchronous writes are possible, but they're not
  when using HttpURLConnection because HttpURLConnection sends a last
  chunk message when it's done with its request.  Last chunk
  generates a comet end event, which then requires that the connection
  to the client be closed.
 
  I guess I don't understand why tomcat needs to close the connection
  after an END event.  It seems to me that the last chunk message from
  the client simply indicates that the client is done sending its
  request.  Why does the server need to close the connection when the
  client finishes its request?
 
  Peter
 
  On Jan 19, 2008 6:01 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 
  I'm not sure what HttpURLConnection has to do with Tomcat or comet.
  and yes, asynchronous writes are possible, just not after the END or
  ERROR events have been issued
 
  Filip
 
 
  Peter Warren wrote:
 
  Does that mean that HttpURLConnection cannot be used for comet
  requests with asynchronous (i.e. delayed) responses?
 
  It would seem so to me since HttpURLConnection always sends an END
  message before reading from the server and since the server can no
  longer write to the client after closing the comet event.  Am I
  missing something?  Is there a way to write to the client after the
  comet event is closed?
 
  Would you consider it a bug that HttpURLConnection is implemented that 
  way?
 
  Peter
 
  On Jan 18, 2008 9:21 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] 
  wrote:
 
 
  during end and error, you MUST close the Comet event
 
  Filip
 
 
  Peter Warren wrote:
 
 
  What do I do to make the END event stop repeating?  I don't want to
  close the CometEvent yet because the server is waiting for data to
  send to the client.  If I don't close the comet event, the END event
  repeats incessantly.
 
  I'm using an unsigned applet as a comet client.  To accommodate
  proxies, I've had to change my comet client to use HttpURLConnection
  instead of Sockets.  (Accessing ProxySelector from an applet to create
  a socket with a proxy generates an AccessControlException.)
 
  HttpURLConnection unfortunately sends a 0crlf when its input stream is
  retrieved for reading.  This generates a Comet END event.  Short of
  closing the comet event, how can I make the server stop notifying me
  of END events?  I can't close the comet event because I want to hold
  onto the comet output stream for use later to send data to the client.
 
  From the comet docs:
  EventType.END: End may be called to end the processing of the request.
  Fields that have been initialized in the begin method should be reset.
  After this event has been processed, the request and response objects,
  as well as all their dependent objects will be recycled and used to
  process other requests. End will also be called when data is available
  and the end of file is reached on the request input (this usually

Re: comet end event

2008-01-21 Thread Peter Warren
 as I  mentioned, the last chunk doesn't generate an END event, I tried
 it locally. of course against 6.0.x trunk.

I played around a bit because I was definitely getting an END event
and found: Sending 0crlf does not generate and END event.  However
sending 0crlfcrlf, which is what HttpURLConnection does, does generate
an END (or sometimes a read error - see below...)  Looking at the http
spec, it seems like 0crlfcrlf is actually the proper way to terminate
the chunk body:

   Chunked-Body   = *chunk
last-chunk
trailer
CRLF

   last-chunk = 1*(0) [ chunk-extension ] CRLF

Am I reading that correctly?

Note about END and read error:
When running both the client and the server locally (i.e. little
latency), sending 0crlfcrlf would sometimes generate a read error
(i.e. inputStream.isAvailable()  0 would be true and then number of
bytes read would be  0) and sometimes an END event.

I tried with both sockets and HttpURLConnection and saw similar
behavior.  However when using HttpURLConnection I could add a delay of
50 millis. and guarantee that I always got an end event (see code
below).

I am using the latest 6.0.x trunk updated locally today.

Peter

CLIENT CODE
===
URL url = new URL(http://www.seekspeak.com/CometTest;);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestMethod(POST);
urlConn.setChunkedStreamingMode(-1); // use default chunk length
urlConn.setReadTimeout(0);
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.connect();
PrintWriter out = new PrintWriter(urlConn.getOutputStream(), true);
out.print(test);
out.flush();
 try {
// sleep to guarantee an END event - remove this sleep to
get read error
Thread.sleep(50);
} catch (InterruptedException ie) {
// do nothing
}
urlConn.getInputStream();

COMET SERVLET CODE:
=
public void event(CometEvent cometEvent) throws IOException,
ServletException {
System.out.println(event:  + cometEvent.getEventType() + ,
subtype:  + cometEvent.getEventSubType());
if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.END) {
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
HttpServletRequest request = cometEvent.getHttpServletRequest();
InputStream inputStream = request.getInputStream();
byte[] buf = new byte[512];
do {
int n = inputStream.read(buf); // can throw an IOException
if (n  0) {
System.out.println(Read  + n +  bytes:  + new
String(buf, 0, n) +  for session: 
+ request.getSession(true).getId());
} else if (n  0) {
System.out.println(read error);
return;
}
} while (inputStream.available()  0);
}
}

On Jan 21, 2008 11:53 AM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 answers inline

 Peter Warren wrote:
  First off, thanks for your responses.  The contributors to this list
  are extremely responsive, patient, and helpful, and I really
  appreciate it!
 
  Hmm, in your test case did you set the HttpURLConnection to use
  chunked transfers (setChunkedStreamingMode(...))?  I find if I use
  chunked transfers, the HttpURLConnection sends a last chunk message
  upon reading input from the server, which generates a comet END event
  on the server.  If I don't use chunked transfers, no END event is
  generated because no last chunk is sent by the client.
 
 as I  mentioned, the last chunk doesn't generate an END event, I tried
 it locally. of course against 6.0.x trunk.
  Which brings up an option I never considered: will a comet servlet
  function properly with non-chunked transfer (i.e. no transfer-coding
  header)?  It seems to.
 
 yes, it can, just send a very large content-length header
  Lastly, I'm still a little confused about requiring the comet event to
  be closed on an END event.  Doesn't this mean that tomcat comet can't
  handle pipelined requests?  If a client sends 2 pipelined requests, it
  will send a last chunk to indicate the end of the first request.
  This last chunk will generate an END event on the server, which then
  requires the connection to be closed.  After the comet event is closed
  the server cannot send a response to the client.
 
 pipelined requests are not defined by the HTTP spec for POST methods,
 only for GET
 assuming the pipelining you are talking about is true pipelining :)
 if you just mean, next request, then yes, tomcat handles that just fine,
 and that is why you have to call event.close()
  The END event

Re: comet end event

2008-01-19 Thread Peter Warren
Does that mean that HttpURLConnection cannot be used for comet
requests with asynchronous (i.e. delayed) responses?

It would seem so to me since HttpURLConnection always sends an END
message before reading from the server and since the server can no
longer write to the client after closing the comet event.  Am I
missing something?  Is there a way to write to the client after the
comet event is closed?

Would you consider it a bug that HttpURLConnection is implemented that way?

Peter

On Jan 18, 2008 9:21 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 during end and error, you MUST close the Comet event

 Filip


 Peter Warren wrote:
  What do I do to make the END event stop repeating?  I don't want to
  close the CometEvent yet because the server is waiting for data to
  send to the client.  If I don't close the comet event, the END event
  repeats incessantly.
 
  I'm using an unsigned applet as a comet client.  To accommodate
  proxies, I've had to change my comet client to use HttpURLConnection
  instead of Sockets.  (Accessing ProxySelector from an applet to create
  a socket with a proxy generates an AccessControlException.)
 
  HttpURLConnection unfortunately sends a 0crlf when its input stream is
  retrieved for reading.  This generates a Comet END event.  Short of
  closing the comet event, how can I make the server stop notifying me
  of END events?  I can't close the comet event because I want to hold
  onto the comet output stream for use later to send data to the client.
 
  From the comet docs:
  EventType.END: End may be called to end the processing of the request.
  Fields that have been initialized in the begin method should be reset.
  After this event has been processed, the request and response objects,
  as well as all their dependent objects will be recycled and used to
  process other requests. End will also be called when data is available
  and the end of file is reached on the request input (this usually
  indicates the client has pipelined a request).
 
  This seems to indicate that even if I could get the END event to go
  away quietly, the comet event's output stream might no longer be
  usable anyway.
 
  It seems to me I have 3 options:
  1) figure out how to make the comet END event stop repeating and hope
  it's output stream still works
  2) figure out how to keep HttpURLConnection from sending 0crlf (don't
  know if that can be done)
  2) use sockets with ProxySelector (which requires signing my applet
  and getting users to grant it privileges)
 
  Thanks,
  Peter
 
  -
  To start a new topic, e-mail: users@tomcat.apache.org
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 


 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet end event

2008-01-19 Thread Peter Warren
What java.net.HttpURLConnection has to do with Tomcat and comet is
that HttpURLConnection is Java's implementation of an http client and
will likely be used by people developing comet apps for Tomcat.  In my
case, I want to use it because I can't use raw sockets on my applet
client due to permission problems when trying to use sockets behind a
proxy.

I understand that asynchronous writes are possible, but they're not
when using HttpURLConnection because HttpURLConnection sends a last
chunk message when it's done with its request.  Last chunk
generates a comet end event, which then requires that the connection
to the client be closed.

I guess I don't understand why tomcat needs to close the connection
after an END event.  It seems to me that the last chunk message from
the client simply indicates that the client is done sending its
request.  Why does the server need to close the connection when the
client finishes its request?

Peter

On Jan 19, 2008 6:01 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 I'm not sure what HttpURLConnection has to do with Tomcat or comet.
 and yes, asynchronous writes are possible, just not after the END or
 ERROR events have been issued

 Filip


 Peter Warren wrote:
  Does that mean that HttpURLConnection cannot be used for comet
  requests with asynchronous (i.e. delayed) responses?
 
  It would seem so to me since HttpURLConnection always sends an END
  message before reading from the server and since the server can no
  longer write to the client after closing the comet event.  Am I
  missing something?  Is there a way to write to the client after the
  comet event is closed?
 
  Would you consider it a bug that HttpURLConnection is implemented that way?
 
  Peter
 
  On Jan 18, 2008 9:21 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 
  during end and error, you MUST close the Comet event
 
  Filip
 
 
  Peter Warren wrote:
 
  What do I do to make the END event stop repeating?  I don't want to
  close the CometEvent yet because the server is waiting for data to
  send to the client.  If I don't close the comet event, the END event
  repeats incessantly.
 
  I'm using an unsigned applet as a comet client.  To accommodate
  proxies, I've had to change my comet client to use HttpURLConnection
  instead of Sockets.  (Accessing ProxySelector from an applet to create
  a socket with a proxy generates an AccessControlException.)
 
  HttpURLConnection unfortunately sends a 0crlf when its input stream is
  retrieved for reading.  This generates a Comet END event.  Short of
  closing the comet event, how can I make the server stop notifying me
  of END events?  I can't close the comet event because I want to hold
  onto the comet output stream for use later to send data to the client.
 
  From the comet docs:
  EventType.END: End may be called to end the processing of the request.
  Fields that have been initialized in the begin method should be reset.
  After this event has been processed, the request and response objects,
  as well as all their dependent objects will be recycled and used to
  process other requests. End will also be called when data is available
  and the end of file is reached on the request input (this usually
  indicates the client has pipelined a request).
 
  This seems to indicate that even if I could get the END event to go
  away quietly, the comet event's output stream might no longer be
  usable anyway.
 
  It seems to me I have 3 options:
  1) figure out how to make the comet END event stop repeating and hope
  it's output stream still works
  2) figure out how to keep HttpURLConnection from sending 0crlf (don't
  know if that can be done)
  2) use sockets with ProxySelector (which requires signing my applet
  and getting users to grant it privileges)
 
  Thanks,
  Peter
 
  -
  To start a new topic, e-mail: users@tomcat.apache.org
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 
 
  -
  To start a new topic, e-mail: users@tomcat.apache.org
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 
  -
  To start a new topic, e-mail: users@tomcat.apache.org
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 


 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



comet end event

2008-01-18 Thread Peter Warren
What do I do to make the END event stop repeating?  I don't want to
close the CometEvent yet because the server is waiting for data to
send to the client.  If I don't close the comet event, the END event
repeats incessantly.

I'm using an unsigned applet as a comet client.  To accommodate
proxies, I've had to change my comet client to use HttpURLConnection
instead of Sockets.  (Accessing ProxySelector from an applet to create
a socket with a proxy generates an AccessControlException.)

HttpURLConnection unfortunately sends a 0crlf when its input stream is
retrieved for reading.  This generates a Comet END event.  Short of
closing the comet event, how can I make the server stop notifying me
of END events?  I can't close the comet event because I want to hold
onto the comet output stream for use later to send data to the client.

From the comet docs:
EventType.END: End may be called to end the processing of the request.
Fields that have been initialized in the begin method should be reset.
After this event has been processed, the request and response objects,
as well as all their dependent objects will be recycled and used to
process other requests. End will also be called when data is available
and the end of file is reached on the request input (this usually
indicates the client has pipelined a request).

This seems to indicate that even if I could get the END event to go
away quietly, the comet event's output stream might no longer be
usable anyway.

It seems to me I have 3 options:
1) figure out how to make the comet END event stop repeating and hope
it's output stream still works
2) figure out how to keep HttpURLConnection from sending 0crlf (don't
know if that can be done)
2) use sockets with ProxySelector (which requires signing my applet
and getting users to grant it privileges)

Thanks,
Peter

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Comet Development

2008-01-16 Thread Peter Warren
This post (http://www.nabble.com/comet-questions-td14673697.html#a14673697)
contains test code for both a client  comet servlet.  See if it
helps.

On Jan 16, 2008 10:35 AM, Siobhan [EMAIL PROTECTED] wrote:
 To anyone who has successfully used Comet:



 I've been trying to use Comet with Tomcat 6.0 for a few weeks now and have
 been unsuccessful. I'm so frustrated with the lack of documentation and the
 unusable example that was given with Tomcat.



 Are there any step-by-step instructions on how to successfully implement a
 test program?



 -SB



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: comet questions

2008-01-15 Thread Peter Warren
Anyone else experiencing comet timeout problems with the nio connector
and the latest 6.0.x trunk?

My cometEvent.setTimeout(...) setting is ignored, but I do receive
comet timeouts based on the connectionTimeout setting for the nio
connector.  Setting the connectionTimeout to 10 secs gives me a comet
timeout event every 10 secs.  Setting it to 2 mins gives a comet
timeout every 2 mins.

The docs don't mention any link between the connectionTimeout settings
and comet timeout events that I can find.

Connector config:
Connector port=80
protocol=org.apache.coyote.http11.Http11NioProtocol maxThreads=500
connectionTimeout=1 keepAliveTimeout=3
maxKeepAliveRequests=-1 socket.soKeepAlive=true
socket.appReadBufSize=2048 socket.appWriteBufSize=2048
socket.rxBufSize=2048 socket.txBufSize=2048
acceptorThreadCount=2 redirectPort=8443 /

On Jan 9, 2008 12:23 PM, Peter Warren [EMAIL PROTECTED] wrote:
 Using the nio connector from the latest 6.0.x trunk, I'm failing to
 receive any comet timeouts.  I set the comet timeout to 5 secs but,
 after waiting much longer than 5 secs, the only two events I receive
 are begin and read.

 event: BEGIN, subtype: null
 for servlet: com.seekspeak.server.debug.CometTestServlet
 time: Wed Jan 09 12:12:28 PST 2008
 on cometEvent: [EMAIL PROTECTED]
 with org.apache.tomcat.comet.timeout attribute: null
 with org.apache.tomcat.comet.timeout.support attribute: true
 event: READ, subtype: null
 for servlet: com.seekspeak.server.debug.CometTestServlet
 time: Wed Jan 09 12:12:28 PST 2008
 on cometEvent: [EMAIL PROTECTED]
 with org.apache.tomcat.comet.timeout attribute: 5000
 with org.apache.tomcat.comet.timeout.support attribute: true

 I see that the Http11NioProcessor changed some comet timeout specific
 code from the previous rev.  Could this be having an impact?

 Below is my test client and test servlet.  Am I doing something wrong?

 Thanks,
 Peter

 SERVLET
 ---
 public class CometTestServlet extends HttpServlet implements CometProcessor {

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 System.out.println(event:  + cometEvent.getEventType() + ,
 subtype:  + cometEvent.getEventSubType());
 System.out.println(\tfor servlet:  + this.getClass().getName());
 System.out.println(\ttime:  + new Date(System.currentTimeMillis()));
 System.out.println(\ton cometEvent:  + cometEvent);
 System.out.println(\twith \org.apache.tomcat.comet.timeout\
 attribute: 
 +
 cometEvent.getHttpServletRequest().getAttribute(org.apache.tomcat.comet.timeout));
 System.out.println(\twith
 \org.apache.tomcat.comet.timeout.support\ attribute: 
 +
 cometEvent.getHttpServletRequest().getAttribute(org.apache.tomcat.comet.timeout.support));
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 cometEvent.setTimeout(5 * 1000);
 } else if (cometEvent.getEventType() == CometEvent.EventType.ERROR) {
 cometEvent.close();
 } else if (cometEvent.getEventType() == CometEvent.EventType.END) {
 cometEvent.close();
 } else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
 handleReadEvent(cometEvent);
 }
 }


 private void handleReadEvent(CometEvent cometEvent) throws
 IOException, ServletException {
 ServerCometChannel talker = new ServerCometChannel(cometEvent);
 respond(talker);
 }

 private void respond(ServerCometChannel channel) throws IOException {
 String clientMessage = channel.receive();
 if (clientMessage != null  clientMessage.length()  0) {
 channel.send(comet succeeded);
 }
 }

 private class ServerCometChannel {

 private static final int OUTPUT_BUFFER_SIZE = 512;

 private CometEvent cometEvent;

 private InputStream inputStream;

 private PrintWriter outputWriter;

 public ServerCometChannel(CometEvent cometEvent) throws
 IOException, ServletException {
 this.cometEvent = cometEvent;
 inputStream = cometEvent.getHttpServletRequest().getInputStream();
 OutputStream outputStream =
 cometEvent.getHttpServletResponse().getOutputStream();
 this.outputWriter = new PrintWriter(new BufferedWriter(new
 OutputStreamWriter(outputStream),
 OUTPUT_BUFFER_SIZE));
 }

 private String receive() throws IOException {
 StringBuffer buffer = new StringBuffer();
 byte[] buf = new byte[512];
 while (inputStream.available()  0) {
 int n = inputStream.read(buf);
 if (n  0) {
 buffer.append(new String(buf, 0, n));
 }
 }
 return buffer.toString();
 }

 public void send(String

Re: comet client doesn't receive server response

2008-01-15 Thread Peter Warren
What is interesting to me is that the exact same client code only
using a different url (i.e. to a normal http servlet, not a comet
servlet) succeeds.  Is there something in comet response headers that
an antivirus app or firewall would pick up on?  Why would a request to
a normal servlet succeed and a comet servlet fail?  Keep in mind the
comet servlet has been shown to be funtional on numerous other
machines.

I believe I disabled all firewalls and antivirus on the suspect
machine, but I will double-check.

Thanks for your response,
Peter

On Jan 15, 2008 9:37 AM, Leonardo Fraga
[EMAIL PROTECTED] wrote:
 Hello,

 I've had problems with long http responses and some kind of antiviruses
 and internet firewalls (avg family, basically).
 They put a hook on the winsocket stack for http connections and buffer
 everything you are receiving, until the end (or some high amount of
 data), to run the checks. In my case, this buffering lasts for minutes,
 with no byte sent back to the browser.

 I think this can be a simple point to check...

 Hugs,

 Leonardo Fraga
 Web Developer
 [EMAIL PROTECTED]


 Peter Warren wrote:

 I posted this question along with some others recently.  I'm
 re-posting it in its own thread with some additional information.
 
 I have a comet client app that works on all the machines I've tested
 except one.  The failing machine sends a comet request to the server
 and then waits indefinitely for the response, even though the server
 has sent the response and flushed the buffer.  I'm trying to figure
 out why the client doesn't receive the response and would really
 appreciate any tips.
 
 Server is latest from 6.0.x trunk and using nio connector.
 
 Failing machine info:
 - runs windows xp
 - windows firewall is turned off
 - fails on multiple networks, so it doesn't seem to be a router or
 firewall issue
 - computer has no problem with other network access
 - same test code pointed at a non-comet servlet (simply changing the
 url) succeeds!!!
 
 I used a socket monitoring tool to see if the client machine receives
 the response at all.  It doesn't appear to.  Below are traces from a
 successful machine and the failing machine.  I'm not a sockets expert,
 so I don't really know what to look for, but the two things that stand
 out to me are:
 - failing machine uses localhost ip instead of its LAN ip (which is
 192.168.1.102 according to ipconfig)
   - succeeding machine uses LAN ip
   - I don't understand why they're different
 - failing machine receives WSAEWOULDBLOCK error instead of server response
 
 I believe the WSAEWOULDBLOCK basically indicates that there's nothing
 on the socket to be read, which seems to indicate that the failing
 machine never receives the response at all.
 
 Is this a comet problem?  Is it a routing problem?  Anyone have any
 ideas for what the problem might be?  Any tips on what I should
 investigate next?
 
 Thanks,
 Peter
 
 SUCCEEDING MACHINE SOCKET TRACE
 =
 Connect 
 Address:   66.241.85.247:80
 Return Value:  0
 Error Code:0
 
 GetSockName 
 Address:   192.168.1.133:1104
 Return Value:  0
 Error Code:0
 
 SetSockOpt -
 Level: SOL_SOCKET
 Opt Name:  SO_KEEPALIVE
 Opt Len:   4
 Return Value:  0
 Error Code:0
 01 00 00 00 
 
 Send ---
 Address:   192.168.1.133:1104 = 66.241.85.247:80
 Flags: 0
 Return Value:  0
 Error Code:0
 Data:
 POST /servlet/Receive HTTP/1.1
 Host: www.seekspeak.com
 User-Agent: SeekSpeak
 Connection: keep-alive
 Content-Type: text/plain
 Transfer-Encoding: chunked
 
 2c
 source_chat_id=192.168.1.1%3A486547763981705
 
 
 Recv ---
 Address:   192.168.1.133:1104 = 66.241.85.247:80
 Flags: 0
 Return Value:  0
 Error Code:0
 Data:
 HTTP/1.1 200 OK
 Server: Apache-Coyote/1.1
 Set-Cookie: JSESSIONID=4618F4394D4924A5629628ED1CD2ADDE; Path=/
 Transfer-Encoding: chunked
 Date: Thu, 10 Jan 2008 07:55:05 GMT
 
 49
 OK
 COMMAND
 INVITATION_ACCEPTED
 tutorial_client
 Invitation accepted...
 
 
 FAILING MACHINE SOCKET TRACE
 =
 Connect 
 Address:   66.241.85.247:80
 Return Value:  0
 Error Code:0
 
 GetSockName 
 Address:   127.0.0.1:2085
 Return Value:  0
 Error Code:0
 
 SetSockOpt -
 Level: SOL_SOCKET
 Opt Name:  SO_KEEPALIVE
 Opt Len:   4
 Return Value:  0
 Error Code:0
 01 00 00 00 
 
 Send ---
 Address:   127.0.0.1:2085 = 66.241.85.247:80
 Flags: 0

comet client doesn't receive server response

2008-01-10 Thread Peter Warren
I posted this question along with some others recently.  I'm
re-posting it in its own thread with some additional information.

I have a comet client app that works on all the machines I've tested
except one.  The failing machine sends a comet request to the server
and then waits indefinitely for the response, even though the server
has sent the response and flushed the buffer.  I'm trying to figure
out why the client doesn't receive the response and would really
appreciate any tips.

Server is latest from 6.0.x trunk and using nio connector.

Failing machine info:
- runs windows xp
- windows firewall is turned off
- fails on multiple networks, so it doesn't seem to be a router or
firewall issue
- computer has no problem with other network access
- same test code pointed at a non-comet servlet (simply changing the
url) succeeds!!!

I used a socket monitoring tool to see if the client machine receives
the response at all.  It doesn't appear to.  Below are traces from a
successful machine and the failing machine.  I'm not a sockets expert,
so I don't really know what to look for, but the two things that stand
out to me are:
- failing machine uses localhost ip instead of its LAN ip (which is
192.168.1.102 according to ipconfig)
  - succeeding machine uses LAN ip
  - I don't understand why they're different
- failing machine receives WSAEWOULDBLOCK error instead of server response

I believe the WSAEWOULDBLOCK basically indicates that there's nothing
on the socket to be read, which seems to indicate that the failing
machine never receives the response at all.

Is this a comet problem?  Is it a routing problem?  Anyone have any
ideas for what the problem might be?  Any tips on what I should
investigate next?

Thanks,
Peter

SUCCEEDING MACHINE SOCKET TRACE
=
Connect 
Address:   66.241.85.247:80
Return Value:  0
Error Code:0

GetSockName 
Address:   192.168.1.133:1104
Return Value:  0
Error Code:0

SetSockOpt -
Level: SOL_SOCKET
Opt Name:  SO_KEEPALIVE
Opt Len:   4
Return Value:  0
Error Code:0
01 00 00 00 

Send ---
Address:   192.168.1.133:1104 = 66.241.85.247:80
Flags: 0
Return Value:  0
Error Code:0
Data:
POST /servlet/Receive HTTP/1.1
Host: www.seekspeak.com
User-Agent: SeekSpeak
Connection: keep-alive
Content-Type: text/plain
Transfer-Encoding: chunked

2c
source_chat_id=192.168.1.1%3A486547763981705


Recv ---
Address:   192.168.1.133:1104 = 66.241.85.247:80
Flags: 0
Return Value:  0
Error Code:0
Data:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=4618F4394D4924A5629628ED1CD2ADDE; Path=/
Transfer-Encoding: chunked
Date: Thu, 10 Jan 2008 07:55:05 GMT

49
OK
COMMAND
INVITATION_ACCEPTED
tutorial_client
Invitation accepted...


FAILING MACHINE SOCKET TRACE
=
Connect 
Address:   66.241.85.247:80
Return Value:  0
Error Code:0

GetSockName 
Address:   127.0.0.1:2085
Return Value:  0
Error Code:0

SetSockOpt -
Level: SOL_SOCKET
Opt Name:  SO_KEEPALIVE
Opt Len:   4
Return Value:  0
Error Code:0
01 00 00 00 

Send ---
Address:   127.0.0.1:2085 = 66.241.85.247:80
Flags: 0
Return Value:  0
Error Code:0
Data:
POST /servlet/Receive HTTP/1.1
Host: www.seekspeak.com
User-Agent: SeekSpeak
Connection: keep-alive
Content-Type: text/plain
Transfer-Encoding: chunked

2c
source_chat_id=192.168.1.1%3A485374421886120


Select -
Return Value:  0
Error Code:0

Recv ---
Address:   127.0.0.1:2077 = 66.241.85.247:80
Flags: 0
Return Value:  -1
Error Code:WSAEWOULDBLOCK

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



comet questions

2008-01-07 Thread Peter Warren
I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
last Friday.

1) My comet event timeout setting being honored.  How come?  I set the
timeout for 3 hours but a timeout event gets generated every 2
minutes.  If I inspect the comet event for which the timeout is
triggered, I see a setting for the request attribute of:
org.apache.tomcat.comet.timeout=1080.

I set it as follows:

public void event(CometEvent cometEvent) throws IOException,
ServletException {
...
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
// COMET_TIMEOUT = 3 * 60 * 60 * 1000
cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);

Do I need to set something else as well?

2) Occasionally I'm getting a comet event of type ERROR without any
subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
indicate?  I don't see any errors in my catalina log.

3) Reading the response from a comet servlet fails for one of my
client machines.  I wrote a simple test to check the problem.  This
test succeeds for many other users.  For the failing client, the
client request is received by the comet servlet, and the servlet's
response is written and flushed to the stream.  The client then simply
waits indefinitely trying to read the response.  The failing client is
a Windows XP machine.  Could anyone shed some light on why this might
be happening, or give me some clues as to how to debug?  Could it be a
firewall issue on the client end, a router issue on my end?

The test is currently up at: http://www.seekspeak.com/test.html.  It
tests: a http connection to a normal servlet, then a comet connection
to a comet servlet using httpurlconnection, then a comet connection to
a comet servlet using a socket.  For the failing client, both comet
tests fail.

Below is some of the test code for the raw socket test.

Thanks for any help!

Peter

CLIENT
--
private void testCometConnection() throws IOException {
...
URL url = new URL(http://www.seekspeak.com/CometTest;);
channel = new CometChannel(url);
Thread testThread = new Thread() {
public void run() {
try {
channel.send(test);
String received = channel.receive();
...
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
};
testThread.start();
...
}

private class CometChannel {

private static final int INPUT_BUFFER_SIZE = 512;

private static final int OUTPUT_BUFFER_SIZE = 512;

private static final String DELIMITER = \r\n;

private URL url;

private BufferedReader inputReader;

private PrintWriter outputWriter;

private Socket socket;

public CometChannel(URL url) throws IOException {
this.url = url;
initConnection();
}

private void initSocket() throws IOException {
int port = url.getPort();
port = (port  0) ? url.getDefaultPort() : port;
try {
socket = new Socket(url.getHost(), port);
socket.setKeepAlive(true);
inputReader = new BufferedReader(new
InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
outputWriter = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()),
OUTPUT_BUFFER_SIZE));
} catch (NoRouteToHostException nrthe) {
System.out.println(host:  + url.getHost());
nrthe.printStackTrace();
}
}

private void initConnection() throws IOException {
initSocket();
sendHeaders();
}

private void sendHeaders() {
String path = url.getPath();
StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append(POST  + path +  HTTP/1.1 + DELIMITER);
outputBuffer.append(Host:  + url.getHost() + DELIMITER);
outputBuffer.append(User-Agent: CometTestApplet + DELIMITER);
outputBuffer.append(Connection: keep-alive + DELIMITER);
outputBuffer.append(Content-Type: text/plain + DELIMITER);
outputBuffer.append(Transfer-Encoding: chunked + DELIMITER);
outputBuffer.append(DELIMITER);
synchronized (outputWriter) {
outputWriter.print(outputBuffer.toString());
}
}

public void send(String chunkData) throws IOException {
// chunk length field in hex
String hexChunkLength = Integer.toHexString(chunkData.length());

StringBuffer outputBuffer = new StringBuffer();
outputBuffer.append(hexChunkLength);
outputBuffer.append(DELIMITER);
outputBuffer.append(chunkData);

Re: comet questions

2008-01-07 Thread Peter Warren
Using the NIO connector: protocol=org.apache.coyote.http11.Http11NioProtocol.

I'll add response.flushBuffer() and see if that helps.

The tomcat version I was testing against was current with svn as of
last Friday.  I just updated and the only files that are new are:
catalina.policy
STATUS.txt
changelog.xml

Any ideas about the timeout setting or the comet error event without a subtype?

Thanks for your response!

Peter

On Jan 7, 2008 12:44 PM, Filip Hanik - Dev Lists [EMAIL PROTECTED] wrote:
 what connector are you using?
 I would try to use response.flushBuffer when you wanna flush it out (ie
 after you've written to and flushed your stream).

 also, there have been some bug fixes, that you can get from SVN, or wait
 for 6.0.16 to come out

 Filip


 Peter Warren wrote:
  I have some comet questions.  I'm using the tomcat 6.0.x trunk as of
  last Friday.
 
  1) My comet event timeout setting being honored.  How come?  I set the
  timeout for 3 hours but a timeout event gets generated every 2
  minutes.  If I inspect the comet event for which the timeout is
  triggered, I see a setting for the request attribute of:
  org.apache.tomcat.comet.timeout=1080.
 
  I set it as follows:
 
  public void event(CometEvent cometEvent) throws IOException,
  ServletException {
...
  if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
// COMET_TIMEOUT = 3 * 60 * 60 * 1000
  cometEvent.setTimeout(TimingConstants.COMET_TIMEOUT);
 
  Do I need to set something else as well?
 
  2) Occasionally I'm getting a comet event of type ERROR without any
  subtype (i.e. not TIMEOUT, CLIENT_DISCONNECT, etc.).  What does that
  indicate?  I don't see any errors in my catalina log.
 
  3) Reading the response from a comet servlet fails for one of my
  client machines.  I wrote a simple test to check the problem.  This
  test succeeds for many other users.  For the failing client, the
  client request is received by the comet servlet, and the servlet's
  response is written and flushed to the stream.  The client then simply
  waits indefinitely trying to read the response.  The failing client is
  a Windows XP machine.  Could anyone shed some light on why this might
  be happening, or give me some clues as to how to debug?  Could it be a
  firewall issue on the client end, a router issue on my end?
 
  The test is currently up at: http://www.seekspeak.com/test.html.  It
  tests: a http connection to a normal servlet, then a comet connection
  to a comet servlet using httpurlconnection, then a comet connection to
  a comet servlet using a socket.  For the failing client, both comet
  tests fail.
 
  Below is some of the test code for the raw socket test.
 
  Thanks for any help!
 
  Peter
 
  CLIENT
  --
  private void testCometConnection() throws IOException {
...
  URL url = new URL(http://www.seekspeak.com/CometTest;);
  channel = new CometChannel(url);
  Thread testThread = new Thread() {
  public void run() {
  try {
  channel.send(test);
  String received = channel.receive();
  ...
  }
  } catch (IOException ioe) {
  ioe.printStackTrace();
  }
  }
  };
  testThread.start();
...
  }
 
  private class CometChannel {
 
  private static final int INPUT_BUFFER_SIZE = 512;
 
  private static final int OUTPUT_BUFFER_SIZE = 512;
 
  private static final String DELIMITER = \r\n;
 
  private URL url;
 
  private BufferedReader inputReader;
 
  private PrintWriter outputWriter;
 
  private Socket socket;
 
  public CometChannel(URL url) throws IOException {
  this.url = url;
  initConnection();
  }
 
  private void initSocket() throws IOException {
  int port = url.getPort();
  port = (port  0) ? url.getDefaultPort() : port;
  try {
  socket = new Socket(url.getHost(), port);
  socket.setKeepAlive(true);
  inputReader = new BufferedReader(new
  InputStreamReader(socket.getInputStream()), INPUT_BUFFER_SIZE);
  outputWriter = new PrintWriter(new BufferedWriter(new
  OutputStreamWriter(socket.getOutputStream()),
  OUTPUT_BUFFER_SIZE));
  } catch (NoRouteToHostException nrthe) {
  System.out.println(host:  + url.getHost());
  nrthe.printStackTrace();
  }
  }
 
  private void initConnection() throws IOException {
  initSocket();
  sendHeaders();
  }
 
  private void sendHeaders() {
  String path = url.getPath();
  StringBuffer outputBuffer = new StringBuffer

Re: Tomcat memory issues

2007-09-07 Thread Peter Warren
 As far as I under stand I should NOT close the stream object as I didn't
 open it.

That's my understanding too.  When I said I was keeping connections
open, I meant I was opening connections from the client and not
closing them.  Since I'm using comet servlets, the server keeps the
connections open until the client disconnects.  When I open many
connections, I see classes in my heap similar to those you show.

If you keep a reference to the Request object tucked away somewhere on
the server inadvertently, the associated buffers won't go away and
memory will continue to grow.  Is it possible that you're keeping a
reference to the Request or any of the streams somewhere?  Is it
possible that some of your servlets aren't returning and thus never
closing their connections?

What classes are holding references to these classes?

- org.apache.catalina.connector.ResponseFacade (ACCA)
- class[] (ACCB)
- org.apache.catalina.connector.Request (ACCC)

Peter

On 9/7/07, Morten [EMAIL PROTECTED] wrote:

 Peter Warren [EMAIL PROTECTED] skrev i en meddelelse
 news:[EMAIL PROTECTED]
  Is it possible you're caching Request or Response objects somewhere
  and not releasing them?  I just did a bunch of memory profiling and
  many of the classes you mention are the same classes I see when I open
  and don't close a bunch of connections to the server.
 
 My code in the bottom of the servlet is such:

 ServletOutputStream stream = _response.getOutputStream();
 BufferedOutputStream bos = new BufferedOutputStream(stream);
 bos.write(bytes);
 stream.flush();
 bos.close();

 As far as I under stand I should NOT close the stream object as I didn't
 open it.

 Best regards,

 Morten






 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]



-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Tomcat memory issues

2007-09-06 Thread Peter Warren
Is it possible you're caching Request or Response objects somewhere
and not releasing them?  I just did a bunch of memory profiling and
many of the classes you mention are the same classes I see when I open
and don't close a bunch of connections to the server.

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



comet webapp memory optimization

2007-09-05 Thread Peter Warren
I have a webapp that maintains many concurrent comet connections.
Transmissions between  the client and server are small and infrequent.
 I'm trying to lessen the memory usage by playing with buffer
configurations.

To test various configurations, I wrote a client that opens 2000
connections to a comet  servlet.  Each connection sends a short
message and receives a short message back from the server.  I do not
close the connections.

I'm using the NetBeans 6.0 profiler to look at memory use.

The first thing I did was configure the http connector with the
following settings (maybe a little extreme, but I'm just playing
here):

socket.appReadBufSize=512
socket.appWriteBufSize=512
socket.rxBufSize=512
socket.txBufSize=512

These settings reduced vm heap memory use from 251 MB to 220 MB.

Then I changed my comet servlet to use my own BufferedReader and
PrintWriter with buffer  sizes of 512k, instead of using the Reader
from HttpServletRequest.getReader() and the  Writer from
HttpServletResponse.getWriter(), which both have larger default buffer
sizes.

This reduced memory use from 220 MB to 138 MB.

At this point much of the memory was in char arrays in
org.apache.catalina.connector.InputBuffer objects, and byte arrays in
org.apache.catalina.connector.OutputBuffer objects.  Since I couldn't
find a way to tweak  these buffer sizes with config settings or
external code, I tried modifying the tomcat  code.  I changed the
DEFAULT_BUFFER_SIZE in both those classes to 1024 from 8192.

This reduced memory use from 138 MB to 95 MB.

Now byte arrays in InternalNioInputBuffer and InternalNioOutputBuffer
looked like promising  targets.  To modify these, I changed the
maxHttpHeaderSize in Http11NioProtocol to 1024  from 8192.

This reduced memory use from 95 MB to 66 MB.

At this point my heap map shows the main consumers of memory as follows:

Of the 66 MB on the heap:
char[] account for 26% (below shows %s of the 26%)
  Parameters in Request 56%
  InputBuffer in Request 6%

byte[] 19% (below shows %s of the 19%)
  BufferedInputFilter in Http11NioProcessor 19%
  OutputBuffer in Response 19%
  NioBufferHandler in NioEndpoint 19%
  InternalNioInputBuffer in Http11NioProcessor 20%
  InternalNioOutputBuffer in Http11NioProcessor 18%

So...

1) Are any of the changes listed above bad ideas?  What is the danger
of sizing buffers too small?  Is it just a performance hit, or is
there a danger of losing data?
2) Is there a way for me to change the buffer sizes in InputBuffer,
OutputBuffer, InternalNioInputBuffer, and InternalNioOutputBuffer
without having to change Tomcat code?
3) Does anyone have other ideas for minimizing memory use in a
many-connection, small-data-size webapp?

Thanks,
Peter

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



comet read httpsession timeout

2007-08-16 Thread Peter Warren
A comet read event doesn't update the last accessed time of an
HttpSession -- which means comet read events will never prevent an
http session (not the comet session) from timing out and the
connection getting closed.

Is that by design?  If so, can anyone offer me suggestions on how to
handle long-lived comet connections that may outlive the http session
timeout?

I had been hoping to periodically send a comet read event to update
the access time of the http session.  But, given that comet reads
don't affect access time of the http session, it seems my best option
is to periodically close the comet connection and open a new one.  Or
is there a way for me to programmatically update the http session
access time (I couldn't find one in the HttpSession docs)?  Any other
thoughts?

Thanks,
Peter

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



multiple comet requests

2007-08-14 Thread Peter Warren
How do you send multiple requests to the same comet servlet?

Sending multiple chunks of a single request is fine.  My problem occurs
after the client ends the chunked transaction by sending 0CRLFCRLF to the
server.  The comet servlet correctly registers the END event.

But then the client subsequently tries to initiate a new chunked request by
sending new http headers and a new chunk.  The comet servlet receives a
BEGIN event, immediately followed by an END event.  A READ event is never
generated for the new chunk.  No ERROR events are registered either.

Sequence:
1st request
BEGIN
READ
END

2nd request
BEGIN
END - why an END event and not a READ?

Below are my test client and test comet servlet.  Any thoughts on what I'm
doing wrong?

(I apologize in advance if this is a lack of understanding of http on my
part.  I have looked at the specs and tried to follow the rules but am still
running into problems.)

Thanks,
Peter

-

test servlet
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

public class CometTestServlet extends HttpServlet implements CometProcessor
{
private static final long serialVersionUID = 5472498184127924791L;

public void event(CometEvent cometEvent) throws IOException,
ServletException {
HttpServletRequest request = cometEvent.getHttpServletRequest();
HttpServletResponse response = cometEvent.getHttpServletResponse();
// don't want timeout events
cometEvent.setTimeout(100);
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  + request.getSession(true).getId());
} else if (cometEvent.getEventType() == CometEvent.EventType.ERROR)
{
log(Error for session:  + request.getSession(true).getId() +
,  + cometEvent.getEventSubType());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.END) {
log(End for session:  + request.getSession(true).getId());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
log(Read for session:  + request.getSession(true).getId());
respond(request, response);
}
}

private void respond(HttpServletRequest request, HttpServletResponse
response) throws IOException {
String clientMessage = read(request);

if (clientMessage != null  clientMessage.length()  0) {
response.getWriter().print(clientMessage);
response.getWriter().flush();
}
}

private String read(HttpServletRequest request) throws IOException {
InputStream is = request.getInputStream();
StringBuffer inputBuffer = new StringBuffer();
byte[] buf = new byte[512];
while (is.available()  0) {
int n = is.read(buf); // can throw an IOException
if (n  0) {
inputBuffer.append(new String(buf, 0, n));
log(Read  + n +  bytes:  + new String(buf, 0, n) +  for
session: 
+ request.getSession(true).getId());
} else if (n  0) {
log(comet read error);
}
}
return inputBuffer.toString();
}
}
/test servlet

-

test client
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class CometTestClient1 {

public static final String ENCODING = ISO-8859-1;

private Socket socket;

private OutputStream out;

public static void main(String[] args) throws Exception {
CometTestClient1 test = new CometTestClient1();
test.test();
}

public CometTestClient1() throws IOException {
initConnection();
}

private void initConnection() throws IOException {
socket = new Socket(127.0.0.1, 80);
socket.setKeepAlive(true);
out = socket.getOutputStream();
sendHeaders();
}

private void sendHeaders() throws IOException {
println(GET /CometTest HTTP/1.1);
println(Host: 127.0.0.1);
println(User-Agent: test);
println(Transfer-Encoding: chunked);
println(Connection: keep-alive);
}

private void test() throws IOException {
sendChunkedMessage();
try {
Thread.sleep(6);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
// doesn't seem to matter if I create a new socket connection or not
//initConnection();
sendHeaders();
sendChunkedMessage();

}

private void sendChunkedMessage() throws IOException {
println();
println(10);
print(test data test 1);
out.flush();

 

Re: multiple comet requests

2007-08-14 Thread Peter Warren
Filip, thank you for your very prompt response!  I replaced the
tomcat-coyote.jar with yours and now get the following exception on
startup.  Is there another jar that I need to update?

Thanks,
Peter

Aug 14, 2007 9:02:29 PM org.apache.tomcat.util.digester.Digester startElement
SEVERE: Begin event threw error
java.lang.NoSuchMethodError:
org.apache.tomcat.util.IntrospectionUtils.setProperty(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V
at 
org.apache.catalina.startup.SetAllPropertiesRule.begin(SetAllPropertiesRule.java:66)
at org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1358)
at 
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown
Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown
Source)
at 
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
Source)
at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1644)
at org.apache.catalina.startup.Catalina.load(Catalina.java:504)
at org.apache.catalina.startup.Catalina.load(Catalina.java:538)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:260)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)

 Filip Hanik - Dev Lists wrote:
turns out that if the request is comet, the recycling of the
input/output filter is not happening.
 I have fixed this,
 you can try the tomcat-coyote.jar from
 http://people.apache.org/~fhanik/tomcat/tomcat-coyote.jar

 Filip

 Filip Hanik - Dev Lists wrote:

hi Peter,
thanks for the example, I am able to reproduce this error, let me take
 a look and see why it is happening,

Filip

Peter Warren wrote:
How do you send multiple requests to the same comet servlet?

Sending multiple chunks of a single request is fine.  My problem occurs
after the client ends the chunked transaction by sending 0CRLFCRLF  to the
server.  The comet servlet correctly registers the END event.

But then the client subsequently tries to initiate a new chunked  request by
sending new http headers and a new chunk.  The comet servlet receives a
BEGIN event, immediately followed by an END event.  A READ event is  never
generated for the new chunk.  No ERROR events are registered either.

Sequence:
1st request
BEGIN
READ
END

2nd request
BEGIN
END - why an END event and not a READ?

Below are my test client and test comet servlet.  Any thoughts on  what I'm
doing wrong?

(I apologize in advance if this is a lack of understanding of http on my
part.  I have looked at the specs and tried to follow the rules but  am still
running into problems.)

Thanks,
Peter

-

test servlet
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

public class CometTestServlet extends HttpServlet implements  CometProcessor
{
private static final long serialVersionUID = 5472498184127924791L;

public void event(CometEvent cometEvent) throws IOException,
ServletException {
HttpServletRequest request = cometEvent.getHttpServletRequest();
HttpServletResponse response =  cometEvent.getHttpServletResponse();
// don't want timeout events
cometEvent.setTimeout(100);
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  +  request.getSession(true).getId());
} else if (cometEvent.getEventType() ==  CometEvent.EventType.ERROR)
{
log(Error for session:  +  request.getSession(true).getId() +
,  + cometEvent.getEventSubType());
cometEvent.close();
} else if (cometEvent.getEventType() ==  CometEvent.EventType.END) {
log(End for session

Re: comet read event

2007-06-04 Thread Peter Warren
 serialVersionUID = 5472498184127924791L;

public void event(CometEvent cometEvent) throws IOException,
ServletException {
HttpServletRequest request = cometEvent.getHttpServletRequest();
HttpServletResponse response = cometEvent.getHttpServletResponse();
// don't want timeout events
cometEvent.setTimeout(100);
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  + request.getSession(true).getId());
respond(request, response);
} else if (cometEvent.getEventType() ==
CometEvent.EventType.ERROR) {
log(Error for session:  + request.getSession(true).getId()
+ ,  + cometEvent.getEventSubType());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.END) {
log(End for session:  + request.getSession(true).getId());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
log(Read for session:  + request.getSession(true).getId());
respond(request, response);
}
}

private void respond(HttpServletRequest request, HttpServletResponse
response) throws IOException {
String clientMessage = read(request);
if (clientMessage != null  clientMessage.length()  0) {
response.getWriter().println(clientMessage);
response.getWriter().flush();
}
}

private String read(HttpServletRequest request) throws IOException {
InputStream is = request.getInputStream();
StringBuffer inputBuffer = new StringBuffer();
byte[] buf = new byte[512];
do {
int n = is.read(buf); // can throw an IOException
if (n  0) {
inputBuffer.append(new String(buf, 0, n));
log(Read  + n +  bytes:  + new String(buf, 0, n) + 
for session: 
+ request.getSession(true).getId());
} else if (n  0) {
log(comet read error);
}
} while (is.available()  0);
return inputBuffer.toString();
}
}

Filip Hanik - Dev Lists wrote:
 why don't you make your test available, I'll run it through

 Filip

 Peter Warren wrote:
 Yes, I'm using the NIO connector.  Here is the config line from my
 server.xml:

 Connector port=80
 protocol=org.apache.coyote.http11.Http11NioProtocol maxThreads=150
 connectionTimeout=2 keepAliveTimeout=12
 maxKeepAliveRequests=-1 acceptorThreadCount=2 redirectPort=8443 /

 Are there any other configuration options I need to set?

 Peter

 Filip Hanik - Dev Lists wrote:
  
 and you are using the APR or the NIO connector right?

 Filip

 Peter Warren wrote:

 Thanks for the suggestion.  I changed the comet test servlet to read
 directly from the input stream as shown in the advanced io
 example.  I'm
 still seeing the same behavior.  No comet read event gets generated on
 the server, only the begin event which contains the client's first
 message.  The client then sends its second message and blocks waiting
 for the server.  No events are generated on the server in response to
 the client's second message.  Any other tips for me?

 Thanks,
 Peter

 from the CometTestServlet:

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 ...
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 String clientMessage = read(request);
 if (clientMessage != null  clientMessage.length()  0) {
 response.getWriter().println(clientMessage);
 response.getWriter().flush();
 }
 }
 ...

 private String read(HttpServletRequest request) throws
 IOException {
 InputStream is = request.getInputStream();
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 log(Read  + n +  bytes:  + new String(buf, 0,
 n) + 
 for session: 
 + request.getSession(true).getId());
 } else if (n  0) {
 log(comet read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 from the CometTestClient:

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 String line = read(urlConn.getInputStream());
 System.out.println(line);

 out.println(test 2);
 out.flush();

 line = read(urlConn.getInputStream());
 System.out.println(line);

 out.close();
 urlConn.disconnect();
 }

 private String read(InputStream is) throws IOException {
 StringBuffer inputBuffer = new

Re: [solved] comet read event

2007-06-01 Thread Peter Warren
My client code was the problem.  I had been thinking of the comet
interaction with the server as similar to a socket, open it once and
then read and write merrily from either end.  I forgot that comet is
still operating over http and the client needs to send http headers for
each request.  So the fix in my client code is simply to open a new
HttpURLConnection for each client request, which hopefully does not
establish a new socket connection to the server each time (Each
HttpURLConnection instance is used to make a single request but the
underlying network connection to the HTTP server may be transparently
shared by other instances -- from javadoc for HttpURLConnection).  See
added initConnection() line below.

Peter

### from CometTestClient below ###

public void test() throws IOException {
out.println(test 1);
out.flush();

String line = read(urlConn.getInputStream());
System.out.println(line);

---initConnection(); // reconnect to url - sends new http headers
out.println(test 2);
out.flush();

line = read(urlConn.getInputStream());
System.out.println(line);

out.close();
urlConn.disconnect();
}


Peter Warren wrote:
 Thanks for the suggestion.  I changed the comet test servlet to read
 directly from the input stream as shown in the advanced io example.  I'm
 still seeing the same behavior.  No comet read event gets generated on
 the server, only the begin event which contains the client's first
 message.  The client then sends its second message and blocks waiting
 for the server.  No events are generated on the server in response to
 the client's second message.  Any other tips for me?

 Thanks,
 Peter

 from the CometTestServlet:

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 ...
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  + request.getSession(true).getId());
 String clientMessage = read(request);
 if (clientMessage != null  clientMessage.length()  0) {
 response.getWriter().println(clientMessage);
 response.getWriter().flush();
 }
 }
 ...

 private String read(HttpServletRequest request) throws IOException {
 InputStream is = request.getInputStream();
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 log(Read  + n +  bytes:  + new String(buf, 0, n) + 
 for session: 
 + request.getSession(true).getId());
 } else if (n  0) {
 log(comet read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 from the CometTestClient:

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 String line = read(urlConn.getInputStream());
 System.out.println(line);

 out.println(test 2);
 out.flush();

 line = read(urlConn.getInputStream());
 System.out.println(line);

 out.close();
 urlConn.disconnect();
 }

 private String read(InputStream is) throws IOException {
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 } else if (n  0) {
 return (read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 Filip Hanik - Dev Lists wrote:
   
 take a look at the documentation, the way you are reading it is
 incorrect.
 you need to take advantage of the available() method

 Filip

 Peter Warren wrote:
 
 My BEGIN block in my comet servlet now looks like the code below (added
 a while loop to read until the buffer is empty).  Is that what you had
 in mind?  The buffer in the BEGIN event only contains the client's first
 message.  Am I not emptying the buffer correctly?  Although, I wouldn't
 expect the buffer to contain the client's second message since the
 client blocks for an ack from the server before sending its second
 message.  Any other thoughts on what happens to the client's second
 message and why no READ event is generated?

 Thanks for your help,
 Peter

 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 BufferedReader reader =
 cometEvent.getHttpServletRequest().getReader();
 String line = null;
 while ((line = reader.readLine()) != null) {
 log(servlet

Re: [maybe not solved] comet read event

2007-06-01 Thread Peter Warren
Hmm, ok.  Sending the headers up causes the comet servlet to behave as I
expected, one BEGIN event generated on the first client request and one
READ event generated on the second request.  In my simple test, the
comet servlet doesn't receive the headers as data.  If I don't send up
the headers on the second request, the READ event is never generated (in
fact no event is generated) and the client hangs waiting for a response
from the comet servlet.  Doesn't your cometgui send the headers with
each request?

Peter

Filip Hanik - Dev Lists wrote:
 you're treading dangerous waters my friend. the comet is somewhat like
 a real socket, and sending up new HTTP headers might end up just being
 data for the Comet servlet.

 Filip

 Peter Warren wrote:
 My client code was the problem.  I had been thinking of the comet
 interaction with the server as similar to a socket, open it once and
 then read and write merrily from either end.  I forgot that comet is
 still operating over http and the client needs to send http headers for
 each request.  So the fix in my client code is simply to open a new
 HttpURLConnection for each client request, which hopefully does not
 establish a new socket connection to the server each time (Each
 HttpURLConnection instance is used to make a single request but the
 underlying network connection to the HTTP server may be transparently
 shared by other instances -- from javadoc for HttpURLConnection).  See
 added initConnection() line below.

 Peter

 ### from CometTestClient below ###

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 String line = read(urlConn.getInputStream());
 System.out.println(line);

 ---initConnection(); // reconnect to url - sends new http headers
 out.println(test 2);
 out.flush();

 line = read(urlConn.getInputStream());
 System.out.println(line);

 out.close();
 urlConn.disconnect();
 }


 Peter Warren wrote:
  
 Thanks for the suggestion.  I changed the comet test servlet to read
 directly from the input stream as shown in the advanced io example. 
 I'm
 still seeing the same behavior.  No comet read event gets generated on
 the server, only the begin event which contains the client's first
 message.  The client then sends its second message and blocks waiting
 for the server.  No events are generated on the server in response to
 the client's second message.  Any other tips for me?

 Thanks,
 Peter

 from the CometTestServlet:

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 ...
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 String clientMessage = read(request);
 if (clientMessage != null  clientMessage.length()  0) {
 response.getWriter().println(clientMessage);
 response.getWriter().flush();
 }
 }
 ...

 private String read(HttpServletRequest request) throws
 IOException {
 InputStream is = request.getInputStream();
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 log(Read  + n +  bytes:  + new String(buf, 0, n)
 + 
 for session: 
 + request.getSession(true).getId());
 } else if (n  0) {
 log(comet read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 from the CometTestClient:

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 String line = read(urlConn.getInputStream());
 System.out.println(line);

 out.println(test 2);
 out.flush();

 line = read(urlConn.getInputStream());
 System.out.println(line);

 out.close();
 urlConn.disconnect();
 }

 private String read(InputStream is) throws IOException {
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 } else if (n  0) {
 return (read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 Filip Hanik - Dev Lists wrote:
  
 take a look at the documentation, the way you are reading it is
 incorrect.
 you need to take advantage of the available() method

 Filip

 Peter Warren wrote:
  
 My BEGIN block in my comet servlet now looks like the code below
 (added
 a while loop to read until the buffer is empty

Re: comet read event

2007-05-23 Thread Peter Warren
Thanks for the suggestion.  I changed the comet test servlet to read
directly from the input stream as shown in the advanced io example.  I'm
still seeing the same behavior.  No comet read event gets generated on
the server, only the begin event which contains the client's first
message.  The client then sends its second message and blocks waiting
for the server.  No events are generated on the server in response to
the client's second message.  Any other tips for me?

Thanks,
Peter

from the CometTestServlet:

public void event(CometEvent cometEvent) throws IOException,
ServletException {
...
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  + request.getSession(true).getId());
String clientMessage = read(request);
if (clientMessage != null  clientMessage.length()  0) {
response.getWriter().println(clientMessage);
response.getWriter().flush();
}
}
...

private String read(HttpServletRequest request) throws IOException {
InputStream is = request.getInputStream();
StringBuffer inputBuffer = new StringBuffer();
byte[] buf = new byte[512];
do {
int n = is.read(buf); // can throw an IOException
if (n  0) {
inputBuffer.append(new String(buf, 0, n));
log(Read  + n +  bytes:  + new String(buf, 0, n) + 
for session: 
+ request.getSession(true).getId());
} else if (n  0) {
log(comet read error);
}
} while (is.available()  0);
return inputBuffer.toString();
}

from the CometTestClient:

public void test() throws IOException {
out.println(test 1);
out.flush();

String line = read(urlConn.getInputStream());
System.out.println(line);

out.println(test 2);
out.flush();

line = read(urlConn.getInputStream());
System.out.println(line);

out.close();
urlConn.disconnect();
}

private String read(InputStream is) throws IOException {
StringBuffer inputBuffer = new StringBuffer();
byte[] buf = new byte[512];
do {
int n = is.read(buf); // can throw an IOException
if (n  0) {
inputBuffer.append(new String(buf, 0, n));
} else if (n  0) {
return (read error);
}
} while (is.available()  0);
return inputBuffer.toString();
}

Filip Hanik - Dev Lists wrote:
 take a look at the documentation, the way you are reading it is
 incorrect.
 you need to take advantage of the available() method

 Filip

 Peter Warren wrote:
 My BEGIN block in my comet servlet now looks like the code below (added
 a while loop to read until the buffer is empty).  Is that what you had
 in mind?  The buffer in the BEGIN event only contains the client's first
 message.  Am I not emptying the buffer correctly?  Although, I wouldn't
 expect the buffer to contain the client's second message since the
 client blocks for an ack from the server before sending its second
 message.  Any other thoughts on what happens to the client's second
 message and why no READ event is generated?

 Thanks for your help,
 Peter

 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 BufferedReader reader =
 cometEvent.getHttpServletRequest().getReader();
 String line = null;
 while ((line = reader.readLine()) != null) {
 log(servlet received:  + line);
   
 cometEvent.getHttpServletResponse().getWriter().println(servlet
 received:  + line);
 cometEvent.getHttpServletResponse().getWriter().flush();
 }
 }

  
 Filip Hanik wrote:

 it could be because the data from the request already came in with the
 
 request.
  
 when the BEGIN happens, perform the actions as if there was a READ as
 
 well, ie, empty out the buffer.
  
 Filip
 

 Peter Warren wrote:
  
 The following client code generates a comet BEGIN event on the server
 but not a subsequent READ event, as I was expecting.  How come?  Is my
 code wrong?  Are my expectations wrong?  See sequence of events
 commented in code below.

 // client test method that sends messages to server and listens for
 responses
 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 // server receives client's message, generates a BEGIN event,
 and sends response to client

 in = new BufferedReader(new
 InputStreamReader(urlConn.getInputStream()));
 System.out.println(in.readLine());

 // client receives server's response and prints it

 out.println(test 2);
 out.flush();

 System.out.println(in.readLine

Re: comet read event

2007-05-23 Thread Peter Warren
Yes, I'm using the NIO connector.  Here is the config line from my
server.xml:

Connector port=80
protocol=org.apache.coyote.http11.Http11NioProtocol maxThreads=150
connectionTimeout=2 keepAliveTimeout=12
maxKeepAliveRequests=-1 acceptorThreadCount=2 redirectPort=8443 /

Are there any other configuration options I need to set?

Peter

Filip Hanik - Dev Lists wrote:
 and you are using the APR or the NIO connector right?

 Filip

 Peter Warren wrote:
 Thanks for the suggestion.  I changed the comet test servlet to read
 directly from the input stream as shown in the advanced io example.  I'm
 still seeing the same behavior.  No comet read event gets generated on
 the server, only the begin event which contains the client's first
 message.  The client then sends its second message and blocks waiting
 for the server.  No events are generated on the server in response to
 the client's second message.  Any other tips for me?

 Thanks,
 Peter

 from the CometTestServlet:

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 ...
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 String clientMessage = read(request);
 if (clientMessage != null  clientMessage.length()  0) {
 response.getWriter().println(clientMessage);
 response.getWriter().flush();
 }
 }
 ...

 private String read(HttpServletRequest request) throws IOException {
 InputStream is = request.getInputStream();
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 log(Read  + n +  bytes:  + new String(buf, 0, n) + 
 for session: 
 + request.getSession(true).getId());
 } else if (n  0) {
 log(comet read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 from the CometTestClient:

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 String line = read(urlConn.getInputStream());
 System.out.println(line);

 out.println(test 2);
 out.flush();

 line = read(urlConn.getInputStream());
 System.out.println(line);

 out.close();
 urlConn.disconnect();
 }

 private String read(InputStream is) throws IOException {
 StringBuffer inputBuffer = new StringBuffer();
 byte[] buf = new byte[512];
 do {
 int n = is.read(buf); // can throw an IOException
 if (n  0) {
 inputBuffer.append(new String(buf, 0, n));
 } else if (n  0) {
 return (read error);
 }
 } while (is.available()  0);
 return inputBuffer.toString();
 }

 Filip Hanik - Dev Lists wrote:
  
 take a look at the documentation, the way you are reading it is
 incorrect.
 you need to take advantage of the available() method

 Filip

 Peter Warren wrote:

 My BEGIN block in my comet servlet now looks like the code below
 (added
 a while loop to read until the buffer is empty).  Is that what you had
 in mind?  The buffer in the BEGIN event only contains the client's
 first
 message.  Am I not emptying the buffer correctly?  Although, I
 wouldn't
 expect the buffer to contain the client's second message since the
 client blocks for an ack from the server before sending its second
 message.  Any other thoughts on what happens to the client's second
 message and why no READ event is generated?

 Thanks for your help,
 Peter

 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 BufferedReader reader =
 cometEvent.getHttpServletRequest().getReader();
 String line = null;
 while ((line = reader.readLine()) != null) {
 log(servlet received:  + line);
  
 cometEvent.getHttpServletResponse().getWriter().println(servlet
 received:  + line);

 cometEvent.getHttpServletResponse().getWriter().flush();
 }
 }

  
  
 Filip Hanik wrote:

 it could be because the data from the request already came in with
 the
 
 request.
  
  
 when the BEGIN happens, perform the actions as if there was a READ as
 
 well, ie, empty out the buffer.
  
  
 Filip
 
 Peter Warren wrote:
  
  
 The following client code generates a comet BEGIN event on the server
 but not a subsequent READ event, as I was expecting.  How come? 
 Is my
 code wrong?  Are my expectations wrong?  See sequence of events
 commented

comet read event

2007-05-22 Thread Peter Warren
The following client code generates a comet BEGIN event on the server
but not a subsequent READ event, as I was expecting.  How come?  Is my
code wrong?  Are my expectations wrong?  See sequence of events
commented in code below.

// client test method that sends messages to server and listens for
responses
public void test() throws IOException {
out.println(test 1);
out.flush();

// server receives client's message, generates a BEGIN event,
and sends response to client

in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));
System.out.println(in.readLine());

// client receives server's response and prints it

out.println(test 2);
out.flush();

System.out.println(in.readLine());

// client code blocks here waiting for server response.
// server never generates a READ event.  How come?
// Does the HttpURLConnection (see full code below) need to be
set up differently?
// Am I using the PrintWriter incorrectly when sending to the
comet servlet?

out.close();
urlConn.disconnect();
}

Thanks for any help,
Peter

-- system --

using:
tomcat 6.0.13 on windows xp sp 2
java 1.6.0_01

-- test client  comet servlet source below --

## begin test client ##

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class CometTestClient {

private HttpURLConnection urlConn;

private PrintWriter out;

private BufferedReader in;

public static void main(String[] args) throws Exception {
CometTestClient test = new CometTestClient();
test.test();
}

public CometTestClient() throws IOException {
initConnection();
}

private void initConnection() throws IOException {
URL url = new URL(http://127.0.0.1/CometTest;);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.connect();
out = new PrintWriter(urlConn.getOutputStream());
}

public void test() throws IOException {
out.println(test 1);
out.flush();

in = new BufferedReader(new
InputStreamReader(urlConn.getInputStream()));
System.out.println(in.readLine());

out.println(test 2);
out.flush();

System.out.println(in.readLine());

out.close();
urlConn.disconnect();
}
}

## end test client ##

## begin comet servlet ##

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

public class CometTestServlet extends HttpServlet implements
CometProcessor {
private static final long serialVersionUID = 5472498184127924791L;

public void event(CometEvent cometEvent) throws IOException,
ServletException {
HttpServletRequest request = cometEvent.getHttpServletRequest();
// don't want timeout events
cometEvent.setTimeout(100);
if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  + request.getSession(true).getId());
BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
String line = reader.readLine();
if (line != null) {
log(servlet received:  + line);
   
cometEvent.getHttpServletResponse().getWriter().println(servlet
received:  + line);
cometEvent.getHttpServletResponse().getWriter().flush();
} else {
cometEvent.close();
}
} else if (cometEvent.getEventType() ==
CometEvent.EventType.ERROR) {
log(Error for session:  + request.getSession(true).getId()
+ ,  + cometEvent.getEventSubType());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.END) {
log(End for session:  + request.getSession(true).getId());
cometEvent.close();
} else if (cometEvent.getEventType() == CometEvent.EventType.READ) {
log(Read for session:  + request.getSession(true).getId());
BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
String line = reader.readLine();
if (line != null) {
   
cometEvent.getHttpServletResponse().getWriter().println(servlet
received:  + line);
} else {
cometEvent.close();
}
}
}
}

## end comet servlet ##

-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL 

comet read event

2007-05-22 Thread Peter Warren
My BEGIN block in my comet servlet now looks like the code below (added
a while loop to read until the buffer is empty).  Is that what you had
in mind?  The buffer in the BEGIN event only contains the client's first
message.  Am I not emptying the buffer correctly?  Although, I wouldn't
expect the buffer to contain the client's second message since the
client blocks for an ack from the server before sending its second
message.  Any other thoughts on what happens to the client's second
message and why no READ event is generated?

Thanks for your help,
Peter

if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
log(Begin for session:  + request.getSession(true).getId());
BufferedReader reader =
cometEvent.getHttpServletRequest().getReader();
String line = null;
while ((line = reader.readLine()) != null) {
log(servlet received:  + line);
   
cometEvent.getHttpServletResponse().getWriter().println(servlet
received:  + line);
cometEvent.getHttpServletResponse().getWriter().flush();
}
}

 Filip Hanik wrote:

 it could be because the data from the request already came in with the
request.
 when the BEGIN happens, perform the actions as if there was a READ as
well, ie, empty out the buffer.

 Filip

Peter Warren wrote:
 The following client code generates a comet BEGIN event on the server
 but not a subsequent READ event, as I was expecting.  How come?  Is my
 code wrong?  Are my expectations wrong?  See sequence of events
 commented in code below.

 // client test method that sends messages to server and listens for
 responses
 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 // server receives client's message, generates a BEGIN event,
 and sends response to client

 in = new BufferedReader(new
 InputStreamReader(urlConn.getInputStream()));
 System.out.println(in.readLine());

 // client receives server's response and prints it

 out.println(test 2);
 out.flush();

 System.out.println(in.readLine());

 // client code blocks here waiting for server response.
 // server never generates a READ event.  How come?
 // Does the HttpURLConnection (see full code below) need to be
 set up differently?
 // Am I using the PrintWriter incorrectly when sending to the
 comet servlet?

 out.close();
 urlConn.disconnect();
 }

 Thanks for any help,
 Peter

 -- system --

 using:
 tomcat 6.0.13 on windows xp sp 2
 java 1.6.0_01

 -- test client  comet servlet source below --

 ## begin test client ##

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;

 public class CometTestClient {

 private HttpURLConnection urlConn;

 private PrintWriter out;

 private BufferedReader in;

 public static void main(String[] args) throws Exception {
 CometTestClient test = new CometTestClient();
 test.test();
 }

 public CometTestClient() throws IOException {
 initConnection();
 }

 private void initConnection() throws IOException {
 URL url = new URL(http://127.0.0.1/CometTest;);
 urlConn = (HttpURLConnection) url.openConnection();
 urlConn.setDoInput(true);
 urlConn.setDoOutput(true);
 urlConn.connect();
 out = new PrintWriter(urlConn.getOutputStream());
 }

 public void test() throws IOException {
 out.println(test 1);
 out.flush();

 in = new BufferedReader(new
 InputStreamReader(urlConn.getInputStream()));
 System.out.println(in.readLine());

 out.println(test 2);
 out.flush();

 System.out.println(in.readLine());

 out.close();
 urlConn.disconnect();
 }
 }

 ## end test client ##

 ## begin comet servlet ##

 import java.io.BufferedReader;
 import java.io.IOException;

 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;

 import org.apache.catalina.CometEvent;
 import org.apache.catalina.CometProcessor;

 public class CometTestServlet extends HttpServlet implements
 CometProcessor {
 private static final long serialVersionUID = 5472498184127924791L;

 public void event(CometEvent cometEvent) throws IOException,
 ServletException {
 HttpServletRequest request = cometEvent.getHttpServletRequest();
 // don't want timeout events
 cometEvent.setTimeout(100);
 if (cometEvent.getEventType() == CometEvent.EventType.BEGIN) {
 log(Begin for session:  +
 request.getSession(true).getId());
 BufferedReader reader =
 cometEvent.getHttpServletRequest().getReader();
 String line = reader.readLine

Re: virtual host getRealPath

2006-11-05 Thread Peter Warren
Chris,
   
  The application is an image gallery.  I want to be able to drop images into 
directories anywhere underneath the gallery webapp directory and have the 
images automatically displayed as thumbnails in a table.  Users can click on a 
thumbnail for the full-size image.  I have an index.jsp file that creates 
thumbnails for all the images in a directory and then generates the html to 
display them.  Since I don't want to have to drop an index.jsp file into every 
image directory, I set up a forwarding filter that forwards any request for a 
directory to /index.jsp (the filter ignores other request urls).  To get the 
real path of the directory that corresponds to the requested url, I use:
   
  String servletPath = (String) 
request.getAttribute(javax.servlet.forward.servlet_path);
  String realPath = application.getRealPath(servletPath);
   
   You still have to add the request's URI to the end of that. 
   
  I don't seem to.  For example, a request for: 
http://www.nomad.org/gallery/test yields a servlet path of /test/ and a real 
path of:
   
  C:\Documents and Settings\Peter\My 
Documents\dev\webapps\www.nomad.org\gallery\pg
   
  which is just what I need.  Now with the real path, I can process the target 
image directory by making thumbnails if necessary and laying out the html 
thumbnail table.
   
  It's up and working at http://www.nomad.org/gallery.
   
  Peter

 
-
Cheap Talk? Check out Yahoo! Messenger's low  PC-to-Phone call rates.

Re: virtual host getRealPath

2006-11-04 Thread Peter Warren
Hi Chris,

Thanks for your response.  After poking around a little more, it seems that the 
call


application.getRealPath(request.getServletPath())
provides the proper local file path for me.  Any reason not to use that?

Peter


Christopher Schultz [EMAIL PROTECTED] wrote:  Peter,

 I'm trying to figure out why I get repeated directory names when calling
 application.getRealPath(request.getRequestURI()) from an index.jsp
 file. Clearly there's something about virtual hosts and contexts that
 I'm missing.

I suppose you /could/ do this, but usually URIs and directory structures
usually don't map exactly to one another.

 A request for the url: http://www.nomad.org/gallery/
 C:\Documents and Settings\Peter\My 
 Documents\dev\webapps\www.nomad.org\gallery\gallery

Yeah. Since your URL contains the prefix /gallery already, it's being
added. When you call getRealPath, you're getting something rooted in
...\dev\webapps\www.nomad.org\gallery, which is the root of your
webapp. Since /gallery in the URI, too, you're doubling it.

You need to clip out the context path.

This ought to do it for you:

String path = request.getRequestURI();
if(path.startsWith(request.getContextPath()))
path = path.substring(request.getContextPath());
path = application.getRealPath(path);

Note that letting users' URIs drive files being loaded from the disk
might be considered a security risk. I don't know your deployment model
or anything like that; I just figured I'd mention it.

Hope that helps,
-chris



 
-
Cheap Talk? Check out Yahoo! Messenger's low  PC-to-Phone call rates.

virtual host getRealPath

2006-11-03 Thread Peter Warren
 I'm trying to figure out why I get repeated directory names when calling
application.getRealPath(request.getRequestURI()) from an index.jsp
file. Clearly there's something about virtual hosts and contexts that
I'm missing.

Using Tomcat 5.5  6.0 in standalone mode under Windows XP, I see the
following behavior:

A request for the url: http://www.nomad.org/gallery/

yields a real path of:

C:\Documents and Settings\Peter\My 
Documents\dev\webapps\www.nomad.org\gallery\gallery

(note the duplication of the gallery directory)

Why?

In my server.xml file I defined this virtual host:

Host name=www.nomad.org appBase=C:\Documents and Settings\Peter\My
Documents\dev\webapps\www.nomad.org unpackWARs=true autoDeploy=true
xmlValidationfiltered=false xmlNamespaceAware=false
/Host

If I don't define any contexts, the problem occurs.

The problem also occurs if I have either of the following contexts
defined for this host:

Context path=/gallery docBase=gallery / or
Context path=/gallery docBase=/gallery /

If I set the gallery context to:

Context path=/gallery docBase= /

the duplicate folder name goes away, but my gallery web.xml does not get
read.

Thanks for any help,
Peter

 
-
Cheap Talk? Check out Yahoo! Messenger's low  PC-to-Phone call rates.

threads, performance, and exceptions

2006-10-01 Thread Peter Warren
I have an application that links users so they can chat.  My client
operates within a browser.  To be firewall friendly and avoid client
server sockets listening for incoming requests, I implemented the client
so that it makes http requests and sits and waits (maybe for minutes on
end) until it gets a response.  And each client has 2 threads that are
constantly waiting for an http response from 2 different urls (which
ties up 2 servlet threads).  I knew full well that this would be thread
heavy on the tomcat server side but thought I'd try it out.  The server
is tomcat 5.5.20 running on Windows XP Pro with 1GB of RAM.  After some
preliminary load testing, I find I'm able to handle about 500 simulated
users (each sending a message every 30 seconds) concurrently
communicating before getting connection refused messages.  I would like
to improve that.

So with each client having 2 threads constantly waiting on servlet
requests, that's 2 servlet threads per client or 1000 threads on the
server, which seems like a lot to me.  With 500 clients communicating
every 30 seconds, fairly evenly distributed, that's about 16 requests
per second.  It seems like I should be able to do better than that.

Initially when running my load test, I ran into OutOfMemoryErrors:
unable to create new native thread.  Lowering the thread stack size in
Tomcat's configuration dialog seemed to help.  Now the limiting issue is
that my clients receive connection timed out and read timed out
messages. 

On the client I see the following stacks:
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.init(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at
sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown
Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
at com.seekspeak.applet.URLTalker.initConnection(URLTalker.java:44)
at com.seekspeak.applet.URLTalker.send(URLTalker.java:50)
at
com.seekspeak.test.load.RecipientTest$RefreshThread.run(RecipientTest.java:206)

java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown So
urce)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at com.seekspeak.applet.URLTalker.send(URLTalker.java:54)
at
com.seekspeak.test.load.Communicator$ListenThread.run(Communicator.ja
va:217)

In the catalina log, the only problem I see is this stack:

Oct 1, 2006 7:59:01 PM org.apache.catalina.core.StandardWrapperValve invoke
WARNING: Servlet.service() for servlet invoker threw exception
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at
org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:747)
at
org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:777)
at
org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:115)
at
org.apache.coyote.http11.InternalInputBuffer.doRead(InternalInputBuffer.java:712)
at org.apache.coyote.Request.doRead(Request.java:418)
...

CPU-wise the server never breaks a sweat, rarely rising above 5% cpu. 
My load test client is running on a separate machine from the server. 

My question is: how can I best improve the performance?  Is the server
really refusing client connections or is the load test bogging down and
reporting spurious messages (the load test uses many threads as well)? 
Is the high # of threads on the server a problem?  Would running on
Linux or another OS help?  Is there a way for me to minimize the # of
servlet threads required?

Since my servlet threads don't really do anything but sit around
blocking until being notified to complete the client's request, it seems
like I could just have a small number of threads and keep