/** * Create a procedure. * * Users should generally not directly create instances of this. They are created them * implicitly via {@link ProcedureCoordinator#createProcedure(ForeignExceptionDispatcher, * String, byte[], List)}} * * @param coord coordinator to call back to for general errors (e.g. * {@link ProcedureCoordinator#rpcConnectionFailure(String, IOException)}). * @param wakeFreq frequency to check for errors while waiting * @param timeout amount of time to allow the procedure to run before cancelling * @param procName name of the procedure instance * @param args argument data associated with the procedure instance * @param expectedMembers names of the expected members */ public Procedure(ProcedureCoordinator coord, long wakeFreq, long timeout, String procName, byte[] args, List<String> expectedMembers) { this(coord, new ForeignExceptionDispatcher(), wakeFreq, timeout, procName, args, expectedMembers); }
/** * A callback that handles incoming ForeignExceptions. */ @Override public void receive(ForeignException e) { monitor.receive(e); }
@Override public void rethrowExceptionIfFailed() throws ForeignException { monitor.rethrowException(); }
ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getInstance()); List<ServerName> serverNames = master.getServerManager().getOnlineServersList(); List<String> servers = new ArrayList<>(); ForeignException ee = new ForeignException("Interrupted while waiting for roll log procdure to finish", e); monitor.receive(ee); Thread.currentThread().interrupt(); } catch (ForeignException e) { ForeignException ee = new ForeignException("Exception while waiting for roll log procdure to finish", e); monitor.receive(ee); monitor.rethrowException();
@Test public void testSingleDispatcherWithTimer() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(); // add the listeners monitor.addListener(listener1); monitor.addListener(listener2); TimeoutExceptionInjector timer = new TimeoutExceptionInjector(monitor, 1000); timer.start(); timer.trigger(); assertTrue("Monitor didn't get timeout", monitor.hasException()); // verify that that we propagated the error Mockito.verify(listener1).receive(Mockito.any()); Mockito.verify(listener2).receive(Mockito.any()); }
/** * Test that the dispatcher can receive an error via the timer mechanism. */ @Test public void testAttemptTimer() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher orchestrator = new ForeignExceptionDispatcher(); // add the listeners orchestrator.addListener(listener1); orchestrator.addListener(listener2); // now create a timer and check for that error TimeoutExceptionInjector timer = new TimeoutExceptionInjector(orchestrator, 1000); timer.start(); timer.trigger(); // make sure that we got the timer error Mockito.verify(listener1, Mockito.times(1)).receive(Mockito.any()); Mockito.verify(listener2, Mockito.times(1)).receive(Mockito.any()); } }
/** * Tests that a dispatcher only dispatches only the first exception, and does not propagate * subsequent exceptions. */ @Test public void testErrorPropagation() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher dispatcher = new ForeignExceptionDispatcher(); // add the listeners dispatcher.addListener(listener1); dispatcher.addListener(listener2); // create an artificial error dispatcher.receive(EXTEXN); // make sure the listeners got the error Mockito.verify(listener1, Mockito.times(1)).receive(EXTEXN); Mockito.verify(listener2, Mockito.times(1)).receive(EXTEXN); // make sure that we get an exception try { dispatcher.rethrowException(); fail("Monitor should have thrown an exception after getting error."); } catch (ForeignException ex) { assertTrue("Got an unexpected exception:" + ex, ex.getCause() == EXTEXN.getCause()); LOG.debug("Got the testing exception!"); } // push another error, which should be not be passed to listeners dispatcher.receive(EXTEXN2); Mockito.verify(listener1, Mockito.never()).receive(EXTEXN2); Mockito.verify(listener2, Mockito.never()).receive(EXTEXN2); }
this.done = false; ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getInstance()); ForeignException ee = new ForeignException("Interrupted while waiting for procdure to finish", e); monitor.receive(ee); Thread.currentThread().interrupt(); } catch (ForeignException e) { monitor.receive(e);
monitor.rethrowException(); monitor.rethrowException(); LOG.error(reason, e); ForeignException ee = new ForeignException(reason, e); monitor.receive(ee);
@Override public ForeignException getExceptionIfFailed() { return monitor.getException(); }
@Override public boolean hasException() { return monitor.hasException(); }
this.monitor.addListener(new ForeignExceptionListener() { @Override public void receive(ForeignException ee) {
@Override public synchronized void receive(ForeignException e) { // if we already have an exception, then ignore it if (exception != null) return; LOG.debug(name + " accepting received exception" , e); // mark that we got the error if (e != null) { exception = e; } else { exception = new ForeignException(name, ""); } // notify all the listeners dispatch(e); }
/** * Tests that a dispatcher only dispatches only the first exception, and does not propagate * subsequent exceptions. */ @Test public void testErrorPropagation() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher dispatcher = new ForeignExceptionDispatcher(); // add the listeners dispatcher.addListener(listener1); dispatcher.addListener(listener2); // create an artificial error dispatcher.receive(EXTEXN); // make sure the listeners got the error Mockito.verify(listener1, Mockito.times(1)).receive(EXTEXN); Mockito.verify(listener2, Mockito.times(1)).receive(EXTEXN); // make sure that we get an exception try { dispatcher.rethrowException(); fail("Monitor should have thrown an exception after getting error."); } catch (ForeignException ex) { assertTrue("Got an unexpected exception:" + ex, ex.getCause() == EXTEXN.getCause()); LOG.debug("Got the testing exception!"); } // push another error, which should be not be passed to listeners dispatcher.receive(EXTEXN2); Mockito.verify(listener1, Mockito.never()).receive(EXTEXN2); Mockito.verify(listener2, Mockito.never()).receive(EXTEXN2); }
final Path rootDir = mfs.getRootDir(); final Configuration conf = env.getMasterConfiguration(); final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher(); monitorException.receive(new ForeignException("Master CloneSnapshotProcedure", rse)); throw rse;
ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getInstance()); monitor.rethrowException(); if (proc == null) { String msg = "Failed to submit distributed procedure " + desc.getSignature() + " for '" ForeignException ee = new ForeignException("Interrupted while waiting for flush table procdure to finish", e); monitor.receive(ee); Thread.currentThread().interrupt(); } catch (ForeignException e) { ForeignException ee = new ForeignException("Exception while waiting for flush table procdure to finish", e); monitor.receive(ee); monitor.rethrowException();
@Test public void testSingleDispatcherWithTimer() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(); // add the listeners monitor.addListener(listener1); monitor.addListener(listener2); TimeoutExceptionInjector timer = new TimeoutExceptionInjector(monitor, 1000); timer.start(); timer.trigger(); assertTrue("Monitor didn't get timeout", monitor.hasException()); // verify that that we propagated the error Mockito.verify(listener1).receive(Mockito.any()); Mockito.verify(listener2).receive(Mockito.any()); }
/** * Test that the dispatcher can receive an error via the timer mechanism. */ @Test public void testAttemptTimer() { ForeignExceptionListener listener1 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionListener listener2 = Mockito.mock(ForeignExceptionListener.class); ForeignExceptionDispatcher orchestrator = new ForeignExceptionDispatcher(); // add the listeners orchestrator.addListener(listener1); orchestrator.addListener(listener2); // now create a timer and check for that error TimeoutExceptionInjector timer = new TimeoutExceptionInjector(orchestrator, 1000); timer.start(); timer.trigger(); // make sure that we got the timer error Mockito.verify(listener1, Mockito.times(1)).receive(Mockito.any()); Mockito.verify(listener2, Mockito.times(1)).receive(Mockito.any()); } }
@Override public ForeignException getException() { return monitor.getException(); }
/** * Wait for the coordinator task to complete, and verify all the mocks * @param task to wait on * @throws Exception on unexpected failure */ private void waitAndVerifyProc(Procedure proc, VerificationMode prepare, VerificationMode commit, VerificationMode cleanup, VerificationMode finish, boolean opHasError) throws Exception { boolean caughtError = false; try { proc.waitForCompleted(); } catch (ForeignException fe) { caughtError = true; } // make sure that the task called all the expected phases Mockito.verify(proc, prepare).sendGlobalBarrierStart(); Mockito.verify(proc, commit).sendGlobalBarrierReached(); Mockito.verify(proc, finish).sendGlobalBarrierComplete(); assertEquals("Operation error state was unexpected", opHasError, proc.getErrorMonitor() .hasException()); assertEquals("Operation error state was unexpected", opHasError, caughtError); }