Hello,

I have a simple data processing API that lets you "plug in" various types of
input and output streams.  The "engine" (or a subclass that does some
specific processing) is instantiated with a subclass of a "data source" (a
file, a socket, HTTP URL, STDIN, webapp or system resource) and "data sink"
(a file, a socket, STDOUT, or -- this is the problem -- a HTTP servlet
response).  The "data source" has it's own thread, as does the "data sink"
(this is so each input and output mechanism works at the optimal speed).

I'm developing a sort of simple value-added proxy using the above API.  It
reads from a HTTP URL (data source), then modifies the data contained (by
highlighting selected words), then writes it to the servlet response (data
sink).  In the servlet's "doGet" method, it creates the source, engine, and
sink, and passes the HttpServletResponse object to the sink in the sink's
constructor.  Only the sink ever calls response.getWriter() or
response.getOutputStream() (and of course, it doesn't call both or call
either more than once).

I suspect what's going on is that as the sink is running in a separate
thread, sometimes it's quick and behaves correctly, but more often than not,
the "doGet" method terminates before the "run()" method in the sink's main
thread.  At this point, Tomcat probably forcibly calls "close()" on the
output stream, and stops the "sink" object dead in its tracks.

As far as output is concerned, sometimes (very rarely), I get the complete
response, more often I get just the first part of the response, and even
more often still, I get nothing at all except messages on STDERR.  Here are
two examples (first is a tomcat internal message: thrown if I call "close()"
on the servlet output stream if it's apparently already closed by some
[Tomcat] process; second is my own message: thrown if writing to the
servlet's output stream is interrupted by some other [Tomcat] process):
________________________________________

java.lang.NullPointerException
 at org.apache.ajp.tomcat4.Ajp13Response.sendHeaders(Ajp13Response.java:114)
 at
org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.
java:739)
 at
org.apache.catalina.connector.ResponseFacade.flushBuffer(ResponseFacade.java
:212)
 at
org.apache.catalina.connector.ResponseStream.close(ResponseStream.java:224)
 at fr.reflexe.util.dataproc.HttpServletSink.run(HttpServletSink.java:203)
 at java.lang.Thread.run(Thread.java:484)
________________________________________

fr.reflexe.util.dataproc.HttpServletSink: java.io.IOException: Cannot write
to a closed output stream
________________________________________

I found a *temporary* workaround: in "doGet(...)", I tried:


Thread t = Thread.currentThread();
try
{
  t.sleep(1000);
  System.out.println("servlet has woken up");
}
catch (InterruptedException wakeup)
{
  System.err.println(wakeup.toString());
}


This gave the other thread the time to run, no errors were logged, and the
result was correct when viewed in the browser.  So I'd like to implement a
more intelligent solution, in which I make the thread in which "doGet" is
running "sleep" indefinitely ... or more specifically, wait until the other
thread sends a signal that it's done, by calling "Object.notify()" perhaps.

Would this cause any problem for Tomcat if I called "sleep" in this way?

How would Tomcat's thread pooling system react?

Would this have any significant impact when there are concurrent client
requests?

Am I likely to have portability problems with this type of solution if I try
to deploy on some other servlet engines, or should this not be an issue?

Thanks,
Christopher Brown



--
To unsubscribe:   <mailto:[EMAIL PROTECTED]>
For additional commands: <mailto:[EMAIL PROTECTED]>
Troubles with the list: <mailto:[EMAIL PROTECTED]>

Reply via email to