@Override
        public void run() {
            final int idleTime = getSessionDetachTime();
            if (idleTime == -1) {
                return;
            }
            final Duration allowableInactivity = Duration.ofMillis(idleTime);
            final Instant deadline = Instant.now().minus(allowableInactivity);
            for (LocalSession session : detachedSessions.values()) {
                try {
                    final Set<TerminationDelegate> delegates = session.getStreamManager().getTerminationDelegates();
                    if (!delegates.isEmpty()) {
                        if (delegates.stream().allMatch(terminationDelegate -> terminationDelegate.shouldTerminate(allowableInactivity))) {
                            Log.debug("Detached session '{}' ({}) uses termination delegation, that does wants to have this session cleaned up. Terminating session now.", session.getAddress(), session.getStreamID());
                            terminateDetached(session);
                        } else {
                            Log.trace("Detached session '{}' ({}) uses termination delegation, that does not want to have this session cleaned up yet.", session.getAddress(), session.getStreamID());
                        }
                    } else {
                        if (session.getLastActiveDate().toInstant().isBefore(deadline)) {
                            Log.debug("Detached session '{}' ({}) has been detached for longer than {} and will be cleaned up.", session.getAddress(), session.getStreamID(), Duration.ofMillis(idleTime));
                            terminateDetached(session);
                        } else {
                            Log.trace("Detached session '{}' ({}) has been detached for {}, which is not longer than the configured maximum of {}. It will not (yet) be cleaned up.", session.getAddress(), session.getStreamID(), Duration.ofMillis(System.currentTimeMillis()-session.getLastActiveDate().getTime()), Duration.ofMillis(idleTime));
                        }
                    }
                }
                catch (Throwable e) {
                    Log.error("An exception occurred while trying processing detached session '{}' ({}).", session.getAddress(), session.getStreamID(), e);
                }
            }
        }
Close detached client sessions that haven't seen activity.
xmppserver/src/main/java/org/jivesoftware/openfire/SessionManager.java