@Override
 public void run() {
   if (future != null && future.isCancelled()) {
     return;
   }
   if (lifecycle.stoppedOrClosed()) {
     listener.onClose();
   } else {
     listener.onTimeout(this.timeout);
   }
   // note, we rely on the listener to remove itself in case of timeout if needed
 }
 @Override
 public void run(Timeout timeout) throws Exception {
   if (timeout.isCancelled()) {
     return;
   }
   if (lifecycle.stoppedOrClosed()) {
     listener.onClose();
   } else {
     listener.onTimeout(this.timeout);
   }
   // note, we rely on the listener to remove itself in case of timeout if needed
 }