Uploaded image for project: 'ZK'
  1. ZK
  2. ZK-4194

ZK cannot clear disconnected desktops reliably by remove-desktop requests


    • ZK 9.0.0 S0

      Core Issue

      ZK cannot clear disconnected desktops reliably by remove-desktop requests. Such a no-use desktop causes severe memory problems.

      rmDesktop is not sent could be:

      • a browser crashes
      • the network disconnects
      • Chrome energy saver drops a tab

      Too many server push events are queued up problem

      • the user configures >12 hours session timeout

      When scheduling server push events via Executions.schedule or EventQueue.publish (session/application scope) those events are queued in the collection ScheduleInfo DesktopImpl._schedInfos and processed when new requests arrive at server side.

      Sometimes the client disconnects without sending and rmDesktop command, in such cases scheduled server push events queue up in the desktop at serverside, without ever being picked up - using more and more memory. Only when the session times out the desktop is finally removed and the memory is GCed again. (especially with longer session timeouts severe problems can occur, with millions of schedule listeners remaining in memory for a long period of time)

      A mechanism to detect such disconnected desktops would help to prevent memory problems.
      Of course, detecting those desktops directly is not directly possible from the server side.

      Possible Improvement

      One possibility would be to test the interval between the last processing of the _schedInfos collection and adding a scheduled event
      e.g. whenever the a ScheduleListener executes reset the last processing time, and when DesktopImpl.scheduleServerPush is called calculate the difference. If a configurable interval is exceeded (e.g. 5 mins) assume the desktop is not responding anymore and should be destroyed.

      In a normal case a scheduled server push event is picked up within a short period of time. Either piggyback of a normal user event, or by a server push dummy request. So that not picked up schedule event listeners are often a good indication of a disconnected browser.

      Using this approach a small number of event listeners might still remain in the queue until the session times out - a trade-off between simple code and accuracy.

      A trivial custom Desktop implementation can do the following to determine the inactiveInterval:

      	private long lastEmptyTime = Long.MAX_VALUE;
      	public <T extends Event> void scheduleServerPush(EventListener<T> listener, T event) {
      		long now = System.currentTimeMillis();
      		if(now - lastEmptyTime > 5000) {
      			System.out.println("killed desktop: " + this);
      		if(!scheduledServerPush()) { //if queue was empty (i.e. has been processed recently) restart the timer
      			lastEmptyTime = System.currentTimeMillis();
      		super.scheduleServerPush(listener, event);


      1. A more accurate/complex solution would involve active watchdog threads checking the _schedInfos queue in configurable intervals to determine disconnected state.
      2. OrphanDesktopListener_5912.java

            jumperchen jumperchen
            cor3000 cor3000
            0 Vote for this issue
            8 Start watching this issue