public void handleEvent(ReaderEvent event) {
    switch (event.getEventType()) {
      case DONE:
        // Reader will check for the event queue upon the end of the input stream - no need to interrupt.
        readerEvents.add(event);
        break;
      case ERROR:
        readerEvents.add(event);
        if (readerThread == null) {
          throw new RuntimeException("Reader thread is unexpectedly null, during ReaderEvent error " + event.getMessage());
        }
        // Reader is using a blocking socket .. interrupt it.
        if (LOG.isDebugEnabled()) {
          LOG.debug("Interrupting reader thread due to reader event with error " + event.getMessage());
        }
        readerThread.interrupt();
        try {
          socket.close();
        } catch (IOException e) {
          // Leave the client to time out.
          LOG.error("Cannot close the socket on error", e);
        }
        break;
      default:
        throw new RuntimeException("Unhandled ReaderEvent type " + event.getEventType() + " with message " + event.getMessage());
    }
  }
Define success/error events which are passed to the reader from a different thread.
The reader will check for these events on end of input and interruption of the reader thread.
llap-client/src/java/org/apache/hadoop/hive/llap/LlapBaseRecordReader.java