[IDEMPIERE-175] Performance: Use atmosphere ( long pooling, NIO ) server push
This commit is contained in:
parent
92f5d0245c
commit
0174cceaf6
|
@ -9,8 +9,11 @@ import org.zkoss.lang.Library;
|
||||||
import org.zkoss.zk.au.out.AuScript;
|
import org.zkoss.zk.au.out.AuScript;
|
||||||
import org.zkoss.zk.ui.Desktop;
|
import org.zkoss.zk.ui.Desktop;
|
||||||
import org.zkoss.zk.ui.DesktopUnavailableException;
|
import org.zkoss.zk.ui.DesktopUnavailableException;
|
||||||
|
import org.zkoss.zk.ui.Executions;
|
||||||
|
import org.zkoss.zk.ui.UiException;
|
||||||
import org.zkoss.zk.ui.event.Event;
|
import org.zkoss.zk.ui.event.Event;
|
||||||
import org.zkoss.zk.ui.event.EventListener;
|
import org.zkoss.zk.ui.event.EventListener;
|
||||||
|
import org.zkoss.zk.ui.impl.ExecutionCarryOver;
|
||||||
import org.zkoss.zk.ui.sys.DesktopCtrl;
|
import org.zkoss.zk.ui.sys.DesktopCtrl;
|
||||||
import org.zkoss.zk.ui.sys.Scheduler;
|
import org.zkoss.zk.ui.sys.Scheduler;
|
||||||
import org.zkoss.zk.ui.sys.ServerPush;
|
import org.zkoss.zk.ui.sys.ServerPush;
|
||||||
|
@ -31,6 +34,10 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
private final AtomicReference<AtmosphereResource> resource = new AtomicReference<AtmosphereResource>();
|
private final AtomicReference<AtmosphereResource> resource = new AtomicReference<AtmosphereResource>();
|
||||||
private final int timeout;
|
private final int timeout;
|
||||||
|
|
||||||
|
private ThreadInfo _active;
|
||||||
|
private ExecutionCarryOver _carryOver;
|
||||||
|
private final Object _mutex = new Object();
|
||||||
|
|
||||||
public AtmosphereServerPush() {
|
public AtmosphereServerPush() {
|
||||||
String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout");
|
String timeoutString = Library.getProperty("fi.jawsy.jawwa.zk.atmosphere.timeout");
|
||||||
|
@ -43,7 +50,47 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean activate(long timeout) throws InterruptedException, DesktopUnavailableException {
|
public boolean activate(long timeout) throws InterruptedException, DesktopUnavailableException {
|
||||||
throw new UnsupportedOperationException("activate is not supported by AtmosphereServerPush");
|
final Thread curr = Thread.currentThread();
|
||||||
|
if (_active != null && _active.thread.equals(curr)) { //re-activate
|
||||||
|
++_active.nActive;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ThreadInfo info = new ThreadInfo(curr);
|
||||||
|
|
||||||
|
EventListener<Event> task = new EventListener<Event>() {
|
||||||
|
@Override
|
||||||
|
public void onEvent(Event event) throws Exception {
|
||||||
|
if (event.getName().equals("onNewData"))
|
||||||
|
{
|
||||||
|
synchronized (_mutex) {
|
||||||
|
_carryOver = new ExecutionCarryOver(desktop.get());
|
||||||
|
|
||||||
|
synchronized (info) {
|
||||||
|
info.nActive = 1; //granted
|
||||||
|
info.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
_mutex.wait(); //wait until the server push is done
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw UiException.Aide.wrap(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
synchronized (info) {
|
||||||
|
Executions.schedule(desktop.get(), task, new Event("onNewData"));
|
||||||
|
if (info.nActive == 0)
|
||||||
|
info.wait(timeout <= 0 ? 10*60*1000: timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
_carryOver.carryOver();
|
||||||
|
_active = info;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearResource(AtmosphereResource resource) {
|
public void clearResource(AtmosphereResource resource) {
|
||||||
|
@ -59,7 +106,26 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deactivate(boolean stop) {
|
public boolean deactivate(boolean stop) {
|
||||||
throw new UnsupportedOperationException("deactivate is not supported by AtmosphereServerPush");
|
boolean stopped = false;
|
||||||
|
if (_active != null && Thread.currentThread().equals(_active.thread)) {
|
||||||
|
if (--_active.nActive <= 0) {
|
||||||
|
if (stop)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_carryOver.cleanup();
|
||||||
|
_carryOver = null;
|
||||||
|
_active.nActive = 0; //just in case
|
||||||
|
_active = null;
|
||||||
|
|
||||||
|
synchronized (_mutex) {
|
||||||
|
_mutex.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,6 +136,13 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPiggyback() {
|
public void onPiggyback() {
|
||||||
|
Desktop desktop = this.desktop.get();
|
||||||
|
if (desktop == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Executions.getCurrent() != null && _carryOver == null)
|
||||||
|
_carryOver = new ExecutionCarryOver(desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,4 +200,16 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
this.resource.set(null);
|
this.resource.set(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ThreadInfo {
|
||||||
|
private final Thread thread;
|
||||||
|
/** # of activate() was called. */
|
||||||
|
private int nActive;
|
||||||
|
private ThreadInfo(Thread thread) {
|
||||||
|
this.thread = thread;
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return "[" + thread + ',' + nActive + ']';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue