users@grizzly.java.net

Re: OnEvent() never invoked, Comet source code analyzed

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Tue, 13 Jul 2010 23:34:02 +0200

Just a guess, you're trying to call notify() right after you've added
the CometHandler and CometHandler is not getting invoked, am I correct?
According to the current implementation it looks like expected
behavior and you might intercept CometHandler.onInitialize() to send
some initial notification to the just registered CometHandler?

Thanks.
WBR,
Alexey.




On Jul 13, 2010, at 22:21 , Jake Lockerbe wrote:

>
> I downloaded the sources for grizzly-comet 1.9.19-SNAPSHOT and
> analyzed the code.
>
> If my analysis is correct, the Comet Context method onEvent() is
> never invoked because
> the code never adds the CometHandler to the hashmap of handlers in
> the CometContext object.
>
>
> I discovered the following:
>
> 1) CometContext contains a
> ConcurrentHashpMap<CometHandler,CometTask> handlers
>
> 2) The CometContext method addComentHandler(CometHandler handler)
> invokes the overloaded method
> addCometHandler(CometHandler handler, boolean alreadySuspended)
> with the boolean set to false.
>
> Note: This method does not put any instances of handler into the
> handlers property of CometContext
>
> 3) CometContext contains several overloaded notify methods.
>
> notify(final Object attachment) invokes
> notify(Object attachment,int eventType) with an eventType of
> CometEvent.NOTIFY
>
>
> This method (shown below) extracts the keys of the hashmap as a
> Set and then creates an iterator on this set.
> By my estimation, the keyset is empty at this point and the
> iterator points to an empty set.
>
>
> ****************************************************************************************************
> public void notify(Object attachment,int eventType)throws
> IOException {
> CometEvent event = new CometEvent(eventType,this,attachment);
> Iterator<CometHandler> iterator =
> handlers.keySet().iterator();
>
> notificationHandler.setBlockingNotification(blockingNotification);
> notificationHandler.notify(event,iterator);
> if (event.getType() != CometEvent.TERMINATE
> && event.getType() != CometEvent.INTERRUPT) {
> resetSuspendIdleTimeout();
> }
> }
>
> 4) Now when notificationHandler.notify(event,iterator) is invoked,
> the implementing class'
> DefaultNotificationHandler's notify(event,iterator) is actually
> invoked.
>
> Looking at this code, you can see that if the iterator
> (iteratorHandlers) points to an emtpy Set of handlers the
> notify0 method is never invoked. It appears that this method
> (notify0) is the method that actually
> invokes the onEvent() method of CometContext.
>
>
> ************************************************************************************************
> public void notify(final CometEvent cometEvent,final
> Iterator<CometHandler> iteratorHandlers)
> throws IOException {
> if (!spreadNotifyToManyToThreads && !blockingNotification &&
> threadPool != null ){
> threadPool.execute(new Runnable() {
> public void run() {
> while(iteratorHandlers.hasNext()){
> notify0(cometEvent, iteratorHandlers.next());
> }
> }});
> }else {
> while(iteratorHandlers.hasNext()){
> notify(cometEvent,iteratorHandlers.next());
> }
> }
> }
>
>
> protected void notify0(CometEvent cometEvent,CometHandler
> cometHandler) {
> try{
> switch (cometEvent.getType()) {
> case CometEvent.INTERRUPT:
> cometHandler.onInterrupt(cometEvent); break;
> case CometEvent.NOTIFY:
> case CometEvent.READ:
> case CometEvent.WRITE:
> if (cometHandler instanceof
> DefaultConcurrentCometHandler){
>
> ((DefaultConcurrentCometHandler
> )cometHandler).EnQueueEvent(cometEvent);
> break;
> }
> if
> (cometEvent.getCometContext().isActive(cometHandler)){
> synchronized(cometHandler){
> cometHandler.onEvent(cometEvent);
> }
> }
> break;
> case CometEvent.INITIALIZE:
> cometHandler.onInitialize(cometEvent); break;
> case CometEvent.TERMINATE:
> synchronized(cometHandler){
> cometHandler.onTerminate(cometEvent); break;
> }
> default:
> throw ISEempty;
> }
> } catch (Throwable ex) {
> try {
>
> cometEvent.getCometContext().resumeCometHandler(cometHandler);
> } catch (Throwable t) {
> logger.log(Level.FINE, "Resume phase failed: ", t);
> }
> logger.log(Level.FINE, "Notification failed: ", ex);
> }
> }
>
>