private void poll(long timeout, long now, boolean executeDelayedTasks) {
    // send all the requests we can send now
    trySend(now);

    // ensure we don't poll any longer than the deadline for
    // the next scheduled task
    timeout = Math.min(timeout, delayedTasks.nextTimeout(now));
    clientPoll(timeout, now);
    now = time.milliseconds();

    // handle any disconnects by failing the active requests. note that disconnects must
    // be checked immediately following poll since any subsequent call to client.ready()
    // will reset the disconnect status
    checkDisconnects(now);

    // execute scheduled tasks
    if (executeDelayedTasks) delayedTasks.poll(now);

    // try again to send requests since buffer space may have been
    // cleared or a connect finished in the poll
    trySend(now);

    // fail requests that couldn't be sent if they have expired
    failExpiredRequests(now);
  }
 /**
  * Unschedule a task. This will remove all instances of the task from the task queue. This is a
  * no-op if the task is not scheduled.
  *
  * @param task The task to be unscheduled.
  */
 public void unschedule(DelayedTask task) {
   delayedTasks.remove(task);
 }
 /**
  * Schedule a new task to be executed at the given time. This is "best-effort" scheduling and
  * should only be used for coarse synchronization.
  *
  * @param task The task to be scheduled
  * @param at The time it should run
  */
 public void schedule(DelayedTask task, long at) {
   delayedTasks.add(task, at);
 }
 /**
  * Execute delayed tasks now.
  *
  * @param now current time in milliseconds
  * @throws WakeupException if a wakeup has been requested
  */
 public void executeDelayedTasks(long now) {
   delayedTasks.poll(now);
   maybeTriggerWakeup();
 }