@Test public void testTruncatedHistory() throws Exception { ChangeRequestHistory<DataSegmentChangeRequest> history = new ChangeRequestHistory(2); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter one = history.getLastCounter(); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter two = history.getLastCounter(); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter three = history.getLastCounter(); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter four = history.getLastCounter(); Assert.assertTrue(history.getRequestsSince(ChangeRequestHistory.Counter.ZERO).get().isResetCounter()); Assert.assertTrue(history.getRequestsSince(one).get().isResetCounter()); Assert.assertTrue(history.getRequestsSince(two).get().isResetCounter()); ChangeRequestsSnapshot<DataSegmentChangeRequest> snapshot = history.getRequestsSince(three).get(); Assert.assertEquals(1, snapshot.getRequests().size()); Assert.assertEquals(4, snapshot.getCounter().getCounter()); }
/** * Add single segment change update. */ public synchronized void addChangeRequest(T request) { addChangeRequests(ImmutableList.of(request)); }
Counter lastCounter = getLastCounter(); future.set(getRequestsSinceWithoutWait(counter));
/** * Returns Future that lists the segment load/drop requests since given counter. */ public ListenableFuture<ChangeRequestsSnapshot<DataSegmentChangeRequest>> getSegmentChangesSince(ChangeRequestHistory.Counter counter) { if (counter.getCounter() < 0) { synchronized (lock) { Iterable<DataSegmentChangeRequest> segments = Iterables.transform( segmentLookup.keySet(), new Function<DataSegment, DataSegmentChangeRequest>() { @Nullable @Override public SegmentChangeRequestLoad apply(DataSegment input) { return new SegmentChangeRequestLoad(input); } } ); SettableFuture<ChangeRequestsSnapshot<DataSegmentChangeRequest>> future = SettableFuture.create(); future.set(ChangeRequestsSnapshot.success(changes.getLastCounter(), Lists.newArrayList(segments))); return future; } } else { return changes.getRequestsSince(counter); } }
@Test public void testNonImmediateFuture() throws Exception { final ChangeRequestHistory history = new ChangeRequestHistory(); Future<ChangeRequestsSnapshot> future = history.getRequestsSince( ChangeRequestHistory.Counter.ZERO ); Assert.assertFalse(future.isDone()); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestsSnapshot snapshot = future.get(1, TimeUnit.MINUTES); Assert.assertEquals(1, snapshot.getCounter().getCounter()); Assert.assertEquals(1, snapshot.getRequests().size()); }
public void workerDisabled() { Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.SECONDS), "not started"); if (disabled.compareAndSet(false, true)) { changeHistory.addChangeRequest(new WorkerHistoryItem.Metadata(true)); } }
/** * Add batch of segment changes update. */ public synchronized void addChangeRequests(List<T> requests) { for (T request : requests) { changes.add(new Holder<>(request, getLastCounter().inc())); } singleThreadedExecutor.execute(resolveWaitingFuturesRunnable); }
@Test public void testCancel() { final ChangeRequestHistory<DataSegmentChangeRequest> history = new ChangeRequestHistory(); ListenableFuture<ChangeRequestsSnapshot<DataSegmentChangeRequest>> future = history.getRequestsSince( ChangeRequestHistory.Counter.ZERO ); Assert.assertEquals(1, history.waitingFutures.size()); final AtomicBoolean callbackExcecuted = new AtomicBoolean(false); Futures.addCallback( future, new FutureCallback<ChangeRequestsSnapshot<DataSegmentChangeRequest>>() { @Override public void onSuccess(ChangeRequestsSnapshot result) { callbackExcecuted.set(true); } @Override public void onFailure(Throwable t) { callbackExcecuted.set(true); } } ); future.cancel(true); Assert.assertEquals(0, history.waitingFutures.size()); Assert.assertFalse(callbackExcecuted.get()); }
private void resolveWaitingFutures() { final LinkedHashMap<CustomSettableFuture, Counter> waitingFuturesCopy = new LinkedHashMap<>(); synchronized (waitingFutures) { waitingFuturesCopy.putAll(waitingFutures); waitingFutures.clear(); } for (Map.Entry<CustomSettableFuture, Counter> e : waitingFuturesCopy.entrySet()) { try { e.getKey().set(getRequestsSinceWithoutWait(e.getValue())); } catch (Exception ex) { e.getKey().setException(ex); } } }
public void workerEnabled() { Preconditions.checkState(lifecycleLock.awaitStarted(1, TimeUnit.SECONDS), "not started"); if (disabled.compareAndSet(true, false)) { changeHistory.addChangeRequest(new WorkerHistoryItem.Metadata(false)); } }
future.set(ChangeRequestsSnapshot.success(changeHistory.getLastCounter(), Lists.newArrayList(items))); return future; return changeHistory.getRequestsSince(counter);
private synchronized ChangeRequestsSnapshot<T> getRequestsSinceWithoutWait(final Counter counter) Counter lastCounter = getLastCounter();
private void resolveWaitingFutures() { final LinkedHashMap<CustomSettableFuture, Counter> waitingFuturesCopy = new LinkedHashMap<>(); synchronized (waitingFutures) { waitingFuturesCopy.putAll(waitingFutures); waitingFutures.clear(); } for (Map.Entry<CustomSettableFuture, Counter> e : waitingFuturesCopy.entrySet()) { try { e.getKey().set(getRequestsSinceWithoutWait(e.getValue())); } catch (Exception ex) { e.getKey().setException(ex); } } }
@Test public void testCounterHashMismatch() throws Exception { ChangeRequestHistory<DataSegmentChangeRequest> history = new ChangeRequestHistory(3); Assert.assertTrue(history.getRequestsSince(new ChangeRequestHistory.Counter(0, 1234)).get().isResetCounter()); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter one = history.getLastCounter(); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter two = history.getLastCounter(); Assert.assertTrue(history.getRequestsSince(new ChangeRequestHistory.Counter(0, 1234)).get().isResetCounter()); ChangeRequestsSnapshot<DataSegmentChangeRequest> snapshot = history.getRequestsSince(one).get(); Assert.assertEquals(1, snapshot.getRequests().size()); Assert.assertEquals(2, snapshot.getCounter().getCounter()); Assert.assertTrue(history.getRequestsSince(new ChangeRequestHistory.Counter(1, 1234)).get().isResetCounter()); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter three = history.getLastCounter(); history.addChangeRequest(new SegmentChangeRequestNoop()); ChangeRequestHistory.Counter four = history.getLastCounter(); snapshot = history.getRequestsSince(two).get(); Assert.assertEquals(2, snapshot.getRequests().size()); Assert.assertEquals(4, snapshot.getCounter().getCounter()); Assert.assertTrue(history.getRequestsSince(new ChangeRequestHistory.Counter(2, 1234)).get().isResetCounter()); }
@Override public void handle() { synchronized (lock) { final TaskDetails details = runningTasks.get(taskId); if (details == null) { log.warn("Got location notice for task [%s] that isn't running...", taskId); return; } if (!Objects.equals(details.location, location)) { details.location = location; TaskAnnouncement latest = TaskAnnouncement.create( details.task, details.status, details.location ); changeHistory.addChangeRequest(new WorkerHistoryItem.TaskUpdate(latest)); taskAnnouncementChanged(latest); } } } }
/** * Returns Future that lists the segment load/drop requests since given counter. */ public ListenableFuture<ChangeRequestsSnapshot<DataSegmentChangeRequest>> getSegmentChangesSince(ChangeRequestHistory.Counter counter) { if (counter.getCounter() < 0) { synchronized (lock) { Iterable<DataSegmentChangeRequest> segments = Iterables.transform( segmentLookup.keySet(), new Function<DataSegment, DataSegmentChangeRequest>() { @Nullable @Override public SegmentChangeRequestLoad apply(DataSegment input) { return new SegmentChangeRequestLoad(input); } } ); SettableFuture<ChangeRequestsSnapshot<DataSegmentChangeRequest>> future = SettableFuture.create(); future.set(ChangeRequestsSnapshot.success(changes.getLastCounter(), Lists.newArrayList(segments))); return future; } } else { return changes.getRequestsSince(counter); } }
/** * Add batch of segment changes update. */ public synchronized void addChangeRequests(List<T> requests) { for (T request : requests) { changes.add(new Holder(request, getLastCounter().inc())); } singleThreadedExecutor.execute(resolveWaitingFuturesRunnable); }
Counter lastCounter = getLastCounter(); future.set(getRequestsSinceWithoutWait(counter));
changes.addChangeRequests(changesBatch);
@Test public void testSimple() throws Exception { ChangeRequestHistory<DataSegmentChangeRequest> history = new ChangeRequestHistory(); Assert.assertEquals(0, history.getLastCounter().getCounter()); history.addChangeRequest(new SegmentChangeRequestNoop()); Assert.assertEquals(1, history.getLastCounter().getCounter()); ChangeRequestsSnapshot<DataSegmentChangeRequest> snapshot = history.getRequestsSince(ChangeRequestHistory.Counter.ZERO).get(); Assert.assertEquals(1, snapshot.getRequests().size()); Assert.assertEquals(1, snapshot.getCounter().getCounter()); history.addChangeRequest(new SegmentChangeRequestNoop()); Assert.assertEquals(2, history.getLastCounter().getCounter()); snapshot = history.getRequestsSince(snapshot.getCounter()).get(); Assert.assertEquals(1, snapshot.getRequests().size()); Assert.assertEquals(2, snapshot.getCounter().getCounter()); snapshot = history.getRequestsSince(ChangeRequestHistory.Counter.ZERO).get(); Assert.assertEquals(2, snapshot.getRequests().size()); Assert.assertEquals(2, snapshot.getCounter().getCounter()); }