Here is what I understood:

Assumption #1:
================
When you receive a CometEvent.EventType.READ event, you can always read() at 
least one byte from the request's InputStream without blocking.

Is this correct ?
If not correct, then this mail goes directly to trash (and sorry for the 
inconvenience...)

If correct, then returning 1 for InputStream.available() in this context makes 
sense and gives an indication that a read can occur without blocking (without 
the need to convey the same information by a side-channel).
For reference: http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStream.html 
for InputStream.available() method contract with the caller. 

Note that available() returning 0 makes sense also. In this context, it means 
"I cannot guarantee that you can read without blocking".
But returning 0 will force the Comet API user to use the kind of hack I used, 
e.g.: I have read in the Comet API doc that I can read at least one byte 
without blocking and I will use another channel to convey information about it.
For example: 
public void doOnlyNonBlockingReads(InputStream is, boolean 
canReadOneByteEvenIfAvailableReturns0)

The fact that data is not yet read "under the hood" is not an issue as long as 
Assumption#1 is correct, you can read one byte of data without blocking, when 
you decide to call one of the read() methods.

I believe that when making a blocking read in a thread would be a critical 
issue, one should never call InputStream.read() methods if 
InputStream.available() returns 0 ... You simply don't have the guarantee that 
it won't block.

If you don't think that returning 1 for available() in the 
"CometEvent.EventType.READ event case" is a good thing, then 
I can live with a hack in my code ;^) 
I just believe this would make the Comet API better for others and easier to 
use. 
Reading the data on socket before going into the READ event could also be a 
solution to this kind of issue but raises other kind of problems.

Christophe

-----Message d'origine-----
De : Filip Hanik - Dev Lists [mailto:[EMAIL PROTECTED] 
Envoyé : mardi 23 janvier 2007 18:14
À : Tomcat Developers List
Objet : Re: Comet API and InputStream.available()

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]


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

Reply via email to