@Override
  public int get(PageId pageId, int pageOffset, int bytesToRead, ReadTargetBuffer target,
      boolean isTemporary) throws IOException, PageNotFoundException {
    Callable<Integer> callable = () ->
        mPageStore.get(pageId, pageOffset, bytesToRead, target, isTemporary);
    try {
      return mTimeLimter.callWithTimeout(callable, mTimeoutMs, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      // Task got cancelled by others, interrupt the current thread
      // and then throw a runtime ex to make the higher level stop.
      Thread.currentThread().interrupt();
      throw new RuntimeException(e);
    } catch (TimeoutException e) {
      Metrics.STORE_GET_TIMEOUT.inc();
      throw new IOException(e);
    } catch (RejectedExecutionException e) {
      Metrics.STORE_THREADS_REJECTED.inc();
      throw new IOException(e);
    } catch (Throwable t) {
      Throwables.propagateIfPossible(t, IOException.class, PageNotFoundException.class);
      throw new IOException(t);
    }
  }
@Test
  public void getTimeout() throws Exception {
    mPageStore.setGetHanging(true);
    try {
      mTimeBoundPageStore.get(PAGE_ID, 0, PAGE.length, new ByteArrayTargetBuffer(mBuf, 0));
      fail();
    } catch (IOException e) {
      assertTrue(e.getCause() instanceof TimeoutException);
    }
  }