code: protected void checkTimeouts() {
  
  		// Compute timeout limits
  		long now = System.currentTimeMillis();
  		Iterator<NodeDescriptor> i;
  		NodeDescriptor node;
  
  		// Check offline timeout
  		if (offlineTimeout > 0) {
  			i = nodes.values().iterator();
  			long offlineTimeoutMillis = offlineTimeout * 1000L;
  			while (i.hasNext()) {
  				node = i.next();
  				if (node.local) {
  					continue;
  				}
  				node.readLock.lock();
  				try {
  					if (node.offlineSince > 0 && now - node.offlineSince > offlineTimeoutMillis) {
  
  						// Remove node info from registry
  						i.remove();
  						logger.info("Node \"" + node.nodeID + "\" is no longer registered because it was inactive for "
  								+ offlineTimeout + " seconds.");
  
  					}
  				} finally {
  					node.readLock.unlock();
  				}
  			}
  		}
  
  		// Check heartbeat timeout
  		if (heartbeatTimeout > 0) {
  			long heartbeatTimeoutMillis = heartbeatTimeout * 1000L;
  			i = nodes.values().iterator();
  			LinkedList<NodeDescriptor> disconnectedNodes = new LinkedList<>();
  			while (i.hasNext()) {
  				node = i.next();
  				if (node.local) {
  					continue;
  				}
  				node.writeLock.lock();
  				try {
  					if (node.cpuWhen > 0 && now - node.cpuWhen > heartbeatTimeoutMillis && node.markAsOffline()) {
  
  						// Remove services and listeners
  						registry.removeActions(node.nodeID);
  						eventbus.removeListeners(node.nodeID);
  						disconnectedNodes.add(node);
  					}
  				} finally {
  					node.writeLock.unlock();
  				}
  			}
  			i = disconnectedNodes.iterator();
  			while (i.hasNext()) {
  				node = i.next();
  
  				// Notify listeners
  				logger.info("Heartbeat is not received from \"" + node.nodeID + "\" node.");
  				logger.info("Node \"" + node.nodeID + "\" disconnected unexpectedly.");
  				broadcastNodeDisconnected(node.info, true);
  			}
  		}
  	}
docs: --- TIMEOUT PROCESS ---