tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Filip Hanik - Dev Lists <devli...@hanik.com>
Subject Re: Comet API and InputStream.available()
Date Tue, 23 Jan 2007 17:13:48 GMT
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:remm@apache.org] 
> 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: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail:
dev-help@tomcat.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>
>
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message