ok, I'm confused, why would available return 1 when there is no data to be read?
the values for available are
>0 data to be read
0 no data to be read
-1 end of stream reached

I don't think we have -1 in our values, as that would only happen if the client closed the connection, and at that point we will probably call another event, although initially I know the NIO connector calls read with 0 data to be read

Filip

Christophe Pierret wrote:
I suggest a minor update to the behaviour exhibited by the 
CoyoteInputStream.available() method when called from inside a Comet.READ event.
Instead of returning 0 on first call (before trying to read), available() 
should return 1 when initially called, as it seems guaranteed that reading one 
byte won't block.  It is still consistent with InputStream.available() 
documentation :
*  Returns the number of bytes that can be read (or skipped over) from this 
input stream without blocking by the next caller of a method for this input 
stream.

When first read occurs, it should then return the real available bytes.

I had to implement this behaviour myself when using Comet API in my product, since I already had a working implementation for a fragmented packet reader based on ByteBuffer (done for NIO kind of IO). In this case available() would return byteBuffer.limit() - byteBuffer.position().

Please have a look at code fragment at the end of mail to get the idea.
I call InputStreamByteBuffer.setInputStream() only once for each Comet.READ 
event.
Since I cannot afford to do a blocking read, I loop while( (avail= myInputStreamByteBuffer.available())==0 ) and read inside the loop until (avail - count_bytes_read) ==0 ...
My InputStream adapter code is a bit too much convoluted for my taste, but it 
currently works with Comet/CoyoteInputStream.

I think that implementing this kind of behaviour in Tomcat in the InputStream 
returned by HttpServletRequest.getInputStream() would be a good thing.
It could be done either by writing a wrapper around CoyoteInputStream or by 
adding some extra (optional) behaviour to CoyoteInputStream activated only when 
inside a Comet read, or by doing it at the InputBuffer level.

What do you think of this idea ?
If you agree, I volunteer to test the updated code (or even propose a patch for 
it).

Here is the code fragment excerpted from my Inputstream adaptator:
public static class InputStreamByteBuffer implements IByteBuffer
    {
        private InputStream inputStream;
        private boolean fixTomcatAvailable;
        InputStreamByteBuffer(InputStream is)
        {
            this.inputStream = is;
            fixTomcatAvailable = true;
        }

        public InputStream getInputStream()
        {
            return inputStream;
        }

        public void setInputStream(InputStream inputStream)
        {
            fixTomcatAvailable = true;
            this.inputStream = inputStream;
        }

        public int available() throws NPIOException
        {
            try
            {
                int avail = inputStream.available();
                if (avail==0 && fixTomcatAvailable)
                {
return 1; }
                return avail;
            }
            catch (IOException se)
            {
                NPIOException.rethrow(se);
            }
            return 0; // never reached
        }
        public byte get() throws NPIOException
        {
            if (fixTomcatAvailable) fixTomcatAvailable = false;
            return (byte)Serializer.readByte(inputStream);
        }
        public void get(byte[] dst, int offset, int length) throws NPIOException
        {
            if (fixTomcatAvailable) fixTomcatAvailable = false;
            try
            {
                inputStream.read(dst,offset,length);
            }
            catch (IOException se)
            {
                NPIOException.rethrow(se);
            }
        }
} public interface IByteBuffer
    {
        int available() throws NPIOException;
        byte get() throws NPIOException;
        void get(byte[] dst, int offset, int length) throws NPIOException;
    }

Sorry, it was a bit long, but shorter would not have been quite clear... Even 
if I don't think this is very clear yet ;-)
Christophe Pierret


-----Message d'origine-----
De : Remy Maucherat [mailto:[EMAIL PROTECTED] Envoyé : lundi 22 janvier 2007 20:37
À : Tomcat Developers List
Objet : Re: Congratulations to tomcat developers for the Comet API

Christophe Pierret wrote:
I only had to port the patches for
http://issues.apache.org/bugzilla/show_bug.cgi?id=40960
and
http://issues.apache.org/bugzilla/show_bug.cgi?id=37869

These two patches have been merged in HEAD.

Feedback on the Comet API:
- There may be some ways to improve the documentation of the API: from what I saw (I got caught by this one :-), it seems that one need to call CometEvent.close() before throwing an exception in READ events or the event keeps coming back forever. I could not find a reference to this behaviour in documentation.

Throw an exception like what ? If an exception is thrown by something in the event method, it should close the connection with an error without further problems (CoyoteAdapter.event will return false to the connector's event method, which does return a code asking for closing the socket - and more importantly, doesn't put it back in the poller). CometEvent.close() doesn't do much, so I don't understand how it can cause a different behavior.

- Is there a rationale for receiving READ events when request.getInputStream().available()==0 ?

There's a reason: the actual read will be done on the socket when you read on the Java input stream, so it's normal to have available == 0. The event guarantees that the blocking read will not block. Filip suggested having the read done before calling event, but I thought it added complexity.

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: 
[EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to