@Override
      public void run() {
        Random random = new Random();
        Time start = Time.now();

        while (start.elapsedSince().lessThan(duration) && error[0] == null) {
          logger.info(
              "{} elapsed: {}, duration: {}",
              new Object[] {Thread.currentThread().getName(), start.elapsedSince(), duration});
          int page1 = random.nextInt(counts.length);
          int page2 = random.nextInt(counts.length);
          int count = 0;
          while (page2 == page1 && count < 100) {
            page2 = random.nextInt(counts.length);
            count++;
          }
          if (page2 == page1) {
            throw new RuntimeException("orly?");
          }
          try {
            sync.lockPage(page1);
            sync.lockPage(page2);
            // have locks, increment the count

            counts[page1].incrementAndGet();
            counts[page2].incrementAndGet();
            hits.incrementAndGet();

            // hold the lock for some time
            try {
              Thread.sleep(50);
            } catch (InterruptedException e) {
              error[0] = "Worker :" + Thread.currentThread().getName() + " interrupted";
            }

            // decrement the counts
            counts[page1].decrementAndGet();
            counts[page2].decrementAndGet();

            // release lock
          } catch (CouldNotLockPageException e) {
            // ignore
          } finally {
            sync.unlockAllPages();
          }
        }
      }
  public static boolean isConnected(
      final Application application, final String id, final Duration timeout) {
    final Time time = TimerChannelBehavior.getLastPollEvent(application, id);
    boolean isConnected;
    if (time == null) {
      // the behavior has been cleaned
      return false;
    }
    isConnected = time.elapsedSince().compareTo(timeout) < 0;
    if (!isConnected) {
      // timeout expired, the page is probably not connected anymore

      // we clean the metadata to avoid memory leak
      TimerChannelBehavior.cleanMetadata(application, id);
    }
    return isConnected;
  }