Watchdog implements Runnable, BackgroundResource { @Override public void run() { try { runUnsafe(); } catch (Throwable t) { LOG.log(Level.SEVERE, "Caught throwable in periodic Watchdog run. Continuing.", t); } } private  Watchdog(ApiClock clock, Duration scheduleInterval, ScheduledExecutorService executor); static Watchdog create(
      ApiClock clock, Duration scheduleInterval, ScheduledExecutorService executor); ResponseObserver<ResponseT> watch(
      ResponseObserver<ResponseT> innerObserver,
      @Nonnull Duration waitTimeout,
      @Nonnull Duration idleTimeout); @Override void run(); @Override void shutdown(); @Override boolean isShutdown(); @Override boolean isTerminated(); @Override void shutdownNow(); @Override boolean awaitTermination(long duration, TimeUnit unit); @Override void close();  }
@Test public void testWaitTimeout() throws Exception { innerObserver.controller.get(1, TimeUnit.MILLISECONDS).request(1); clock.incrementNanoTime(waitTime.toNanos() - 1); watchdog.run(); assertThat(call.getController().isCancelled()).isFalse(); clock.incrementNanoTime(1); watchdog.run(); assertThat(call.getController().isCancelled()).isTrue(); call.getController() .getObserver() .onError(new RuntimeException("Some upstream exception representing cancellation")); Throwable actualError = null; try { innerObserver.done.get(); } catch (ExecutionException t) { actualError = t.getCause(); } assertThat(actualError).isInstanceOf(WatchdogTimeoutException.class); }
@Test public void testIdleTimeout() throws InterruptedException { clock.incrementNanoTime(idleTime.toNanos() - 1); watchdog.run(); assertThat(call.getController().isCancelled()).isFalse(); clock.incrementNanoTime(1); watchdog.run(); assertThat(call.getController().isCancelled()).isTrue(); call.getController() .getObserver() .onError(new RuntimeException("Some upstream exception representing cancellation")); Throwable actualError = null; try { innerObserver.done.get(); } catch (ExecutionException t) { actualError = t.getCause(); } assertThat(actualError).isInstanceOf(WatchdogTimeoutException.class); }