/** * 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); }
ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher();
/** * If in a running state, creates the specified subprocedure for handling a backup procedure. * @return Subprocedure to submit to the ProcedureMemeber. */ public Subprocedure buildSubprocedure(byte[] data) { // don't run a backup if the parent is stop(ping) if (rss.isStopping() || rss.isStopped()) { throw new IllegalStateException("Can't start backup procedure on RS: " + rss.getServerName() + ", because stopping/stopped!"); } LOG.info("Attempting to run a roll log procedure for backup."); ForeignExceptionDispatcher errorDispatcher = new ForeignExceptionDispatcher(); Configuration conf = rss.getConfiguration(); long timeoutMillis = conf.getLong(BACKUP_TIMEOUT_MILLIS_KEY, BACKUP_TIMEOUT_MILLIS_DEFAULT); long wakeMillis = conf.getLong(BACKUP_REQUEST_WAKE_MILLIS_KEY, BACKUP_REQUEST_WAKE_MILLIS_DEFAULT); LogRollBackupSubprocedurePool taskManager = new LogRollBackupSubprocedurePool(rss.getServerName().toString(), conf); return new LogRollBackupSubprocedure(rss, member, errorDispatcher, wakeMillis, timeoutMillis, taskManager, data); }
ForeignExceptionDispatcher exnDispatcher = new ForeignExceptionDispatcher(table); Configuration conf = rss.getConfiguration(); long timeoutMillis = conf.getLong(FLUSH_TIMEOUT_MILLIS_KEY,
private Path[] addRegion(final SnapshotProtos.SnapshotDescription desc) throws IOException { if (this.snapshotted == tableRegions.length) { throw new UnsupportedOperationException("No more regions in the table"); } RegionData regionData = tableRegions[this.snapshotted++]; ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName()); SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor); manifest.addRegion(regionData.tableDir, regionData.hri); return regionData.files; }
@Test public void testErrorPropagation() throws Exception { List<String> members = new ArrayList<>(); members.add("member"); Procedure proc = new Procedure(coord, new ForeignExceptionDispatcher(), 100, Integer.MAX_VALUE, "op", null, members); final Procedure procspy = spy(proc); ForeignException cause = new ForeignException("SRC", "External Exception"); proc.receive(cause); // start the barrier procedure Thread t = new Thread() { @Override public void run() { procspy.call(); } }; t.start(); t.join(); verify(procspy, never()).sendGlobalBarrierStart(); verify(procspy, never()).sendGlobalBarrierReached(); verify(procspy).sendGlobalBarrierComplete(); }
/** * Setup a procedure member that returns the spied-upon {@link Subprocedure}. */ private void buildCohortMemberPair() throws IOException { dispatcher = new ForeignExceptionDispatcher(); String name = "node"; ThreadPoolExecutor pool = ProcedureMember.defaultPool(name, 1, POOL_KEEP_ALIVE); member = new ProcedureMember(mockMemberComms, pool, mockBuilder); when(mockMemberComms.getMemberName()).thenReturn("membername"); // needed for generating exception Subprocedure subproc = new EmptySubprocedure(member, dispatcher); spySub = spy(subproc); when(mockBuilder.buildSubprocedure(op, data)).thenReturn(spySub); addCommitAnswer(); }
@Test public void testBarrieredErrorPropagation() throws Exception { List<String> members = new ArrayList<>(); members.add("member"); LatchedProcedure proc = new LatchedProcedure(coord, new ForeignExceptionDispatcher(), 100, Integer.MAX_VALUE, "op", null, members); final LatchedProcedure procspy = spy(proc); // start the barrier procedure Thread t = new Thread() { @Override public void run() { procspy.call(); } }; t.start(); // now test that we can put an error in before the commit phase runs procspy.startedAcquireBarrier.await(); ForeignException cause = new ForeignException("SRC", "External Exception"); procspy.receive(cause); procspy.barrierAcquiredByMember(members.get(0)); t.join(); // verify state of all the object verify(procspy).sendGlobalBarrierStart(); verify(procspy).sendGlobalBarrierComplete(); verify(procspy, never()).sendGlobalBarrierReached(); } }
/** * 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()); } }
LatchedProcedure proc = new LatchedProcedure(coord, new ForeignExceptionDispatcher(), 100, Integer.MAX_VALUE, "op", null, members); final LatchedProcedure procspy = spy(proc);
@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()); }
public void consolidate() throws IOException { ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName()); SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor); manifest.addTableDescriptor(htd); manifest.consolidate(); } }
final ForeignExceptionDispatcher dispatcher = new ForeignExceptionDispatcher(); ForeignExceptionDispatcher dispSpy = spy(dispatcher); Subprocedure commit = new EmptySubprocedure(member, dispatcher);
@Override public Void answer(InvocationOnMock invocation) throws Throwable { int index = elem[0]; if (index == memberErrorIndex) { LOG.debug("Sending error to coordinator"); ForeignException remoteCause = new ForeignException("TIMER", new TimeoutException("subprocTimeout" , 1, 2, 0)); Subprocedure r = ((Subprocedure) invocation.getMock()); LOG.error("Remote commit failure, not propagating error:" + remoteCause); comms.receiveAbortProcedure(r.getName(), remoteCause); assertTrue(r.isComplete()); // don't complete the error phase until the coordinator has gotten the error // notification (which ensures that we never progress past prepare) try { Procedure.waitForLatch(coordinatorReceivedErrorLatch, new ForeignExceptionDispatcher(), WAKE_FREQUENCY, "coordinator received error"); } catch (InterruptedException e) { LOG.debug("Wait for latch interrupted, done:" + (coordinatorReceivedErrorLatch.getCount() == 0)); // reset the interrupt status on the thread Thread.currentThread().interrupt(); } } elem[0] = ++index; return null; } }).when(commit).acquireBarrier();
/** * 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());
this.snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshot, rootDir); this.workingDirFs = this.workingDir.getFileSystem(this.conf); this.monitor = new ForeignExceptionDispatcher(snapshot.getName()); this.snapshotManifest = SnapshotManifest.create(conf, rootFs, workingDir, snapshot, monitor);
/** * If in a running state, creates the specified subprocedure for handling a procedure. * @return Subprocedure to submit to the ProcedureMemeber. */ public Subprocedure buildSubprocedure(String name) { // don't run a procedure if the parent is stop(ping) if (rss.isStopping() || rss.isStopped()) { throw new IllegalStateException("Can't start procedure on RS: " + rss.getServerName() + ", because stopping/stopped!"); } LOG.info("Attempting to run a procedure."); ForeignExceptionDispatcher errorDispatcher = new ForeignExceptionDispatcher(); Configuration conf = rss.getConfiguration(); SimpleSubprocedurePool taskManager = new SimpleSubprocedurePool(rss.getServerName().toString(), conf); return new SimpleSubprocedure(rss, member, errorDispatcher, taskManager, name); }
public Path commit() throws IOException { ForeignExceptionDispatcher monitor = new ForeignExceptionDispatcher(desc.getName()); SnapshotManifest manifest = SnapshotManifest.create(conf, fs, snapshotDir, desc, monitor); manifest.addTableDescriptor(htd); manifest.consolidate(); SnapshotDescriptionUtils.completeSnapshot(desc, rootDir, snapshotDir, fs); snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(desc, rootDir); return snapshotDir; }
FileSystem fs = fileSystemManager.getFileSystem(); Path rootDir = fileSystemManager.getRootDir(); final ForeignExceptionDispatcher monitorException = new ForeignExceptionDispatcher();