private static <T> ValueAndBound<T> getInitialCacheValue() { return ValueAndBound.of(Optional.empty(), ValueAndBound.INVALID_BOUND); } }
private static <F, T> Function<ValueAndBound<F>, ValueAndBound<T>> preservingBounds(Function<F, T> base) { return fromValueAndBound -> ValueAndBound.of(fromValueAndBound.value().map(base), fromValueAndBound.bound()); } }
private CheckAndSetResult<ValueAndBound<T>> extractRelevantValues(T targetValue, long newBound, CheckAndSetResult<SequenceAndBound> casResult) { if (casResult.successful()) { return CheckAndSetResult.of(true, ImmutableList.of(ValueAndBound.of(Optional.of(targetValue), newBound))); } return CheckAndSetResult.of( false, casResult.existingValues() .stream() .map(value -> ValueAndBound.of(getValue(value.sequence()), value.bound())) .collect(Collectors.toList())); }
@Override public Optional<ValueAndBound<T>> getAgreedValue() { return getCoordinationValue() .map(sequenceAndBound -> ValueAndBound.of( getValue(sequenceAndBound.sequence()), sequenceAndBound.bound())); }
@Override public CheckAndSetResult<ValueAndBound<T>> transformAgreedValue(Function<ValueAndBound<T>, T> transform) { Optional<SequenceAndBound> coordinationValue = getCoordinationValue(); ValueAndBound<T> extantValueAndBound = ValueAndBound.of(coordinationValue.flatMap( sequenceAndBound -> getValue(sequenceAndBound.sequence())), coordinationValue.map(SequenceAndBound::bound).orElse(SequenceAndBound.INVALID_BOUND)); T targetValue = transform.apply(extantValueAndBound); SequenceAndBound newSequenceAndBound = determineNewSequenceAndBound(coordinationValue, extantValueAndBound, targetValue); CheckAndSetResult<SequenceAndBound> casResult = checkAndSetCoordinationValue( coordinationValue, newSequenceAndBound); return extractRelevantValues(targetValue, newSequenceAndBound.bound(), casResult); }
@Test public void getsLastKnownLocalValueFromDelegateIfPresent() { when(delegate.getLastKnownLocalValue()).thenReturn(Optional.of(ValueAndBound.of(INTEGER_1, BOUND))); assertThat(coordinationService.getLastKnownLocalValue()).contains(ValueAndBound.of(STRING_1, BOUND)); verify(delegate).getLastKnownLocalValue(); verify(intToStringTransform).apply(INTEGER_1); }
@Test public void checkAndSetSuccessfulCase() { when(delegate.tryTransformCurrentValue(any())).thenReturn( CheckAndSetResult.of(true, ImmutableList.of(ValueAndBound.of(INTEGER_1, BOUND)))); CheckAndSetResult<ValueAndBound<String>> casResult = coordinationService.tryTransformCurrentValue(DUMMY_TRANSFORMATION); assertThat(casResult.successful()).isTrue(); assertThat(casResult.existingValues()).containsExactly(ValueAndBound.of(STRING_1, BOUND)); verify(delegate).tryTransformCurrentValue(any()); }
@Test public void checkAndSetFailureCase() { when(delegate.tryTransformCurrentValue(any())).thenReturn( CheckAndSetResult.of(false, ImmutableList.of(ValueAndBound.of(INTEGER_1, BOUND)))); CheckAndSetResult<ValueAndBound<String>> casResult = coordinationService.tryTransformCurrentValue(DUMMY_TRANSFORMATION); assertThat(casResult.successful()).isFalse(); assertThat(casResult.existingValues()).containsExactly(ValueAndBound.of(STRING_1, BOUND)); verify(delegate).tryTransformCurrentValue(any()); }
@Test public void handlesMultitenancyCorrectly() { CoordinationService<InternalSchemaMetadata> otherService = mock(CoordinationService.class); MetricsManager otherManager = MetricsManagers.createForTests(); MetadataCoordinationServiceMetrics.registerMetrics(otherManager, otherService); when(otherService.getLastKnownLocalValue()).thenReturn( Optional.of(ValueAndBound.of(Optional.empty(), TIMESTAMP_2))); assertThat(getGauge(metricsManager, AtlasDbMetricNames.COORDINATION_LAST_VALID_BOUND).getValue()) .isEqualTo(TIMESTAMP_1); assertThat(getGauge(otherManager, AtlasDbMetricNames.COORDINATION_LAST_VALID_BOUND).getValue()) .isEqualTo(TIMESTAMP_2); }
@Test public void getsValueFromDelegateIfPresent() { when(delegate.getValueForTimestamp(anyLong())).thenReturn(Optional.of(ValueAndBound.of(INTEGER_1, BOUND))); assertThat(coordinationService.getValueForTimestamp(BOUND)).contains(ValueAndBound.of(STRING_1, BOUND)); verify(delegate).getValueForTimestamp(BOUND); verify(intToStringTransform).apply(INTEGER_1); }
@Before public void setUp() { when(metadataCoordinationService.getLastKnownLocalValue()) .thenReturn(Optional.of(ValueAndBound.of(INTERNAL_SCHEMA_METADATA, TIMESTAMP_1))); MetadataCoordinationServiceMetrics.registerMetrics(metricsManager, metadataCoordinationService); }
private static <T> ValueAndBound<T> getInitialCacheValue() { return ValueAndBound.of(Optional.empty(), ValueAndBound.INVALID_BOUND); } }
private static <F, T> Function<ValueAndBound<F>, ValueAndBound<T>> preservingBounds(Function<F, T> base) { return fromValueAndBound -> ValueAndBound.of(fromValueAndBound.value().map(base), fromValueAndBound.bound()); } }
private CheckAndSetResult<ValueAndBound<T>> extractRelevantValues(T targetValue, long newBound, CheckAndSetResult<SequenceAndBound> casResult) { if (casResult.successful()) { return CheckAndSetResult.of(true, ImmutableList.of(ValueAndBound.of(Optional.of(targetValue), newBound))); } return CheckAndSetResult.of( false, casResult.existingValues() .stream() .map(value -> ValueAndBound.of(getValue(value.sequence()), value.bound())) .collect(Collectors.toList())); }
@Override public Optional<ValueAndBound<T>> getAgreedValue() { return getCoordinationValue() .map(sequenceAndBound -> ValueAndBound.of( getValue(sequenceAndBound.sequence()), sequenceAndBound.bound())); }
@Override public CheckAndSetResult<ValueAndBound<T>> transformAgreedValue(Function<ValueAndBound<T>, T> transform) { Optional<SequenceAndBound> coordinationValue = getCoordinationValue(); ValueAndBound<T> extantValueAndBound = ValueAndBound.of(coordinationValue.flatMap( sequenceAndBound -> getValue(sequenceAndBound.sequence())), coordinationValue.map(SequenceAndBound::bound).orElse(SequenceAndBound.INVALID_BOUND)); T targetValue = transform.apply(extantValueAndBound); SequenceAndBound newSequenceAndBound = determineNewSequenceAndBound(coordinationValue, extantValueAndBound, targetValue); CheckAndSetResult<SequenceAndBound> casResult = checkAndSetCoordinationValue( coordinationValue, newSequenceAndBound); return extractRelevantValues(targetValue, newSequenceAndBound.bound(), casResult); }