public void registerTimeoutHandler(int commandId, int timeout, Runnable onTimeout) { synchronized (myLock) { myTimeoutHandlers.put( commandId, new TimeoutHandler(onTimeout, System.currentTimeMillis() + timeout)); } scheduleTimeoutCheck(); }
private void scheduleTimeoutCheck() { final Ref<Long> nextTime = Ref.create(Long.MAX_VALUE); synchronized (myLock) { if (myTimeoutHandlers.isEmpty()) return; myTimeoutHandlers.forEachValue( new TObjectProcedure<TimeoutHandler>() { public boolean execute(TimeoutHandler handler) { nextTime.set(Math.min(nextTime.get(), handler.myLastTime)); return true; } }); } final int delay = (int) (nextTime.get() - System.currentTimeMillis() + 100); LOG.debug("schedule timeout check in " + delay + "ms"); if (delay > 10) { myTimeoutAlarm.cancelAllRequests(); myTimeoutAlarm.addRequest(() -> checkTimeout(), delay); } else { checkTimeout(); } }
public void checkTimeout() { LOG.debug("Checking timeout"); final List<TimeoutHandler> timedOut = new ArrayList<>(); synchronized (myLock) { final long time = System.currentTimeMillis(); myTimeoutHandlers.retainEntries( new TIntObjectProcedure<TimeoutHandler>() { public boolean execute(int a, TimeoutHandler b) { if (time > b.myLastTime) { timedOut.add(b); return false; } return true; } }); } for (TimeoutHandler handler : timedOut) { LOG.debug("performing timeout action: " + handler.myAction); handler.myAction.run(); } scheduleTimeoutCheck(); }