@Test public void testSimple() throws IOException, InterruptedException { EventSource src = new NoNlASCIISynthSource(25, 100, 1); EventSink snk = new ConsoleEventSink(); EventSink snk2 = new BenchmarkReportDecorator<EventSink>("report", snk); EventSink snk3 = new BenchmarkInjectDecorator<EventSink>(snk2); DirectDriver connect = new DirectDriver(src, snk3); src.open(); snk3.open(); connect.start(); connect.join(Long.MAX_VALUE); src.close(); snk3.close(); snk2.getReport().toText(new OutputStreamWriter(System.err)); }
@Override public synchronized void stop() throws IOException { thd.stopped = true; try { source.close(); } catch (InterruptedException ee) { LOG.error(ee.getMessage()); } }
@Override public Map<String, Reportable> getSubMetrics() { Map<String, Reportable> map = new HashMap<String, Reportable>(); if (src != null) { map.put("source." + src.getName(), src); } if (snk != null) { map.put("sink." + snk.getName(), snk); } return map; }
@Deprecated public synchronized void getReports(Map<String, ReportEvent> reports) { String phyName = FlumeNode.getInstance().getPhysicalNodeName(); String rprefix = phyName + "." + getName() + "."; if (snk != null) { snk.getReports(rprefix, reports); } if (src != null) { src.getReports(rprefix, reports); } }
@Override public void close() throws IOException { try { src.close(); changeState(tag, State.SENDING, State.SENT); sentCount.incrementAndGet(); } catch (IOException ioe) { LOG.warn("close had a problem " + src, ioe); changeState(tag, null, State.ERROR); throw ioe; // rethrow this } }
@Override public void open() throws IOException { try { src.open(); } catch (IOException ioe) { changeState(tag, State.SENDING, State.ERROR); errCount.incrementAndGet(); // TODO(jon) Eat the exception? throw ioe; } }
@Override public Event next() throws IOException { try { Event e = src.next(); if (e != null) { readEvtCount.incrementAndGet(); // TODO make the roll tag a parameter so that we don't have to remove // it here. e = EventImpl.unselect(e, RollSink.DEFAULT_ROLL_TAG); } updateEventProcessingStats(e); return e; } catch (IOException ioe) { LOG.warn("next had a problem " + src, ioe); changeState(tag, null, State.ERROR); errCount.incrementAndGet(); throw ioe; } }
@Override public void getReports(String namePrefix, Map<String, ReportEvent> reports) { super.getReports(namePrefix, reports); src.getReports(namePrefix + getName() + ".", reports); }
@Override public String toString() { return source.getClass().getSimpleName() + " | " + sink.getName(); }
public void run() { EventSink sink = null; EventSource source = null; synchronized (DirectDriver.this) { sink = DirectDriver.this.sink; source = DirectDriver.this.source; } try { synchronized (stateSignal) { state = DriverState.OPENING; stateSignal.notifyAll(); } source.open(); sink.open(); } catch (Exception e) { // if open is interrupted or has an exception there was a problem. LOG.error("Closing down due to exception on open calls"); errorCleanup(PumperThread.this.getName(), e); return; } synchronized (stateSignal) { lastExn = null; state = DriverState.ACTIVE; stateSignal.notifyAll(); } LOG.debug("Starting driver " + DirectDriver.this); try { Event e = null; while (!stopped) { try { e = source.next(); } catch (InterruptedException eIn) { // If we are interrupted then its time to go down. re-throw the exception. // Details are logged by the outer catch block throw eIn; } catch (Exception eI) { // If this is a chained or converted Interrupt then throw it back if (eI.getCause() instanceof InterruptedException) throw eI; // If there's an exception, try to reopen the source // if the open or close still raises an exception, then bail out LOG.warn("Exception in source: " + source.getName(), eI); LOG.warn("Retrying after Error in source: " + source.getName()); source.close(); source.open(); LOG.info(" Source Retry successful"); e = source.next(); // try to get the next event again } if (e == null) { LOG.warn("{}: Event is null or empty()", source.getName()); if ("NullSource".equals(source.getName())) { break; } else { continue; } } if (e.getBody().length == 0) { LOG.warn("Event is empty; continue"); continue; } nextCount++; try { sink.append(e); } catch (InterruptedException eIn) { // If we are interrupted then its time to go down. re-throw the exception. // Details are logged by the outer catch block throw eIn; } catch (Exception eI) { // If this is a chained or converted Interrupt then throw it back if (eI.getCause() instanceof InterruptedException) throw eI; // If there's an exception, try to reopen the source // if the open or close still raises an exception, then bail out LOG.warn("Exception in sink: " + sink.getName(), eI); LOG.warn("Retrying after Error in source: " + sink.getName()); sink.close(); sink.open(); LOG.info("Sink Retry successful"); sink.append(e); // try to sink the event again } appendCount++; appendBytes += e.getBody().length; } } catch (Exception e1) { // Catches all exceptions or throwables. This is a separate thread LOG.error("Closing down due to exception during append calls"); errorCleanup(PumperThread.this.getName(), e1); return; } try { synchronized (stateSignal) { state = DriverState.CLOSING; stateSignal.notifyAll(); } source.close(); sink.close(); } catch (Exception e) { LOG.error("Closing down due to exception during close calls"); errorCleanup(PumperThread.this.getName(), e); return; } synchronized (stateSignal) { LOG.debug("Driver completed: " + DirectDriver.this); stopped = true; state = DriverState.IDLE; stateSignal.notifyAll(); } }