Hello,
several methods in cometcontext was having bad performance.
first iterating throw all handlers and then for each handler do a hashmap
lookup...
so i made it work with a simple iteration. no extra lookups and its much
fewer lines of code.
places where i fixed this is :
getCometHandler()
initialize()
interrupt()
/**
* Retrive a {_at_link CometHandler} using its SelectionKey. The
* {_at_link SelectionKey} is not exposed to the Comet API, hence this
* method must be protected.
*/
protected CometHandler getCometHandler(SelectionKey key){
for (Entry<CometHandler,SelectionKey> entry:handlers.entrySet()){
if (entry.getValue() == key )
return entry.getKey();
}
return null;
}
/**
* Initialize the newly added {_at_link CometHandler}.
*
* @param attachment An object shared amongst {_at_link CometHandler}.
* @param type The type of notification.
* @param key The SelectionKey representing the CometHandler.
*/
protected void initialize(SelectionKey key) throws IOException {
CometEvent event = new CometEvent<E>();
event.setType(CometEvent.INITIALIZE);
event.setCometContext(this);
for (Entry<CometHandler,SelectionKey> entry:handlers.entrySet()){
SelectionKey ak = entry.getValue();
if(ak != null && ak.equals(key)){
entry.getKey().onInitialize(event);
break;
}
}
}
/**
* Interrupt a {_at_link CometHandler} by invoking {_at_link
CometHandler#onInterrupt}
*/
protected void interrupt(CometTask task){
CometEvent event = new CometEvent<E>();
event.setType(CometEvent.INTERRUPT);
event.attach(null);
event.setCometContext(this);
for (Entry<CometHandler,SelectionKey> entry:handlers.entrySet()){
if (entry.getValue().equals(task.getSelectionKey())){
try{
entry.getKey().onInterrupt(event);
handlers.remove(entry.getKey());
} catch (IOException ex){
logger.log(Level.WARNING,"Exception: ",ex);
}
break;
}
}
activeTasks.remove(task);
}
in notify method, there is no special case for the non polling ,but pure
server pushing usage case.
there is no need to call resetsuspendidle if expiration is not used.
I found no nice way to do this, so i did it this way in my local code:
if (expirationDelay < Long.MAX_VALUE)
resetSuspendIdleTimeout()
heres the entire method:
public void notify(final E attachment,final int eventType,final int
cometHandlerID)
throws IOException{
CometHandler cometHandler = getCometHandler(cometHandlerID);
if (cometHandler == null){
throw new IllegalStateException(INVALID_COMET_HANDLER);
}
CometEvent event = new CometEvent<E>();
event.setType(eventType);
event.attach(attachment);
event.setCometContext(CometContext.this);
notificationHandler.setBlockingNotification(blockingNotification);
notificationHandler.notify(event,cometHandler);
if (event.getType() == CometEvent.TERMINATE
|| event.getType() == CometEvent.INTERRUPT) {
resumeCometHandler(cometHandler);
} else {
if (expirationDelay < Long.MAX_VALUE)
resetSuspendIdleTimeout();
}
}
Also there is a need to make things available for subclass, by changing
private to protected or get set methods.
regards
gustav trede