Ok, one use case scenario would be AJAX requests with asynchronous responses on the server, I can see this be extremely common, I've tried to add in comments to make the example clear, and I don't see this example as stupid, as there are a lot more AJAX client frameworks than Comet client frameworks.

So there are two things we are show casing
1. The ability to write asynchronously
2. The ability to pipeline HTTP requests (assumption: only dealing with GET requests, no HTTP request body) 3. Difference between Comet non blocking and Comet blocking read and writes (note, not related to sockets, API only)

What I'd like to point out is that this example, becomes easier with blocking read/writes, so I've added that at the bottom for comparison

Let me know if I've made any mistakes here, so that we can work with a correct example.

Non blocking read and writes

public class ExampleDelayedAjaxResponse implements CometProcessor {
 ...
 public class DelayedResponder extends Thread {
   public void run() {
     ...
     Client[] clients = getClients();
     for (int i=0; i<clients.length; i++ ) {
       CometEvent event = client.getEvent();
       byte[] data = getDelayedResponse(event);
       if (data!=null) {
         if (event.isWriteable()) {
           event.getHttpServletResponse().getOutputStream().write(data);
           if (event.isWriteable()) { //did we write it all?
              event.close(); //close the event, in anticipation of the next 
request
              event.register(OP_CALLBACK); //triggers an END event
} else { //we didn't write it all, trigger a WRITE event when we are done with the write event.register(OP_WRITE);
           }
         } else {
           //we are not able to write, let us know when we can
           event.register(OP_WRITE);
         }
         //remove the client from the  async thread
         //since we have received the data for this client.
         clients.remove(event);
       }
     }
     ...
   }
 }
 ...
 public void event(CometEvent event) throws IOException, ServletException {
   ...
   if ( event.getEventType() == CometEvent.EventType.BEGIN ) {
     //configure non blocking
     event.configureBlocking(false);
//deregister for READ since we want to enable pipe lining on the connection //for the next HTTP request
     event.unregister(OP_READ);
     //add the client to the list
     clients.add(event);
   } if ( event.getEventType() == CometEvent.EventType.READ ) {
     //read client Id and stock list from client
     //and add the event to our list
     assert("this should never happen");
   } if ( event.getEventType() == CometEvent.EventType.WRITE ) {
     //unregister from the write event
     event.unregister(OP_WRITE);
     //we can now write
byte[] data = getDelayedResponse(event); if ( data != null ) {
       event.getHttpServletResponse().getOutputStream().write(data);
     }
     if( data==null || event.isWriteable() ) {
       event.close();
     }
} if ( event.getEventType() == CometEvent.EventType.END ) { clients.remove(event); } else if (...) {
     ...
   }
   ...
 }
}

Blocking read and writes
public class ExampleDelayedAjaxResponse implements CometProcessor {
 ...
 public class DelayedResponder extends Thread {
   public void run() {
     ...
     Client[] clients = getClients();
     for (int i=0; i<clients.length; i++ ) {
       CometEvent event = client.getEvent();
       byte[] data = getDelayedResponse(event);
       if (data!=null) {
         //register for a write, better do that on a thread pool thread
         //since write is blocking
         event.register(OP_WRITE);
         //remove the client from the  async thread
         clients.remove(event);
       }
     }
     ...
   }
 }
 ...
 public void event(CometEvent event) throws IOException, ServletException {
   ...
   if ( event.getEventType() == CometEvent.EventType.BEGIN ) {
     //configure non blocking
     event.configureBlocking(false);
//deregister for READ since we want to enable pipe lining on the connection //for the next HTTP request
     event.unregister(OP_READ);
     //add the client to the list
     clients.add(event);
   } if ( event.getEventType() == CometEvent.EventType.READ ) {
     //read client Id and stock list from client
     //and add the event to our list
     assert("this should never happen");
   } if ( event.getEventType() == CometEvent.EventType.WRITE ) {
     //unregister from the write event
     event.unregister(OP_WRITE);
     //we can now write
byte[] data = getDelayedResponse(event); //note we don't have to check for null data here
     event.getHttpServletResponse().getOutputStream().write(data);
     event.close();
   } if ( event.getEventType() == CometEvent.EventType.END ) {
     clients.remove(event);
   } else if (...) {
     ...
   }
   ...
 }
}
I think this makes a good use case of where blocking makes life easier, and less complex code. Big difference for both the async thread and the Comet processor.
And this is why I think we should support both, please note 
event.configureBlocking has nothing to do with the underlying socket, just the 
inputstream.read/write.
the underlying socket is an implementation detail.

Remy, would you mind showing this example with sandbox API, I think with a real 
world example, I can understand your API better, and maybe you mine :)

Filip




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

Reply via email to