/** * Gets all the properties for a given page id */ @SuppressWarnings("unchecked") public ImmutableMap<String, ImmutableList<ImmutableMap<String, PageProperty>>> get(final long pageId, Supplier<ImmutableMap<String, ImmutableList<ImmutableMap<String, PageProperty>>>> loader) { return join(cacheRef.get().get(Long.toString(pageId), loader)); }
runAndWaitForStart(() -> cache.get("B", () -> { log.info("{}: About to throw exception", Thread.currentThread().getName()); blockedInFactory.signal(); assertThat(cache.get("A").toCompletableFuture().join(), is(Optional.empty())); assertThat(cache.get("B").toCompletableFuture().join(), is(Optional.empty())); assertThat(cache.get("C").toCompletableFuture().join(), is(Optional.empty()));
@Test public void stableReadExternalCache_normal_marshalling() { final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder() .defaultTtl(Duration.ofSeconds(60)) .entryGrowthRateHint(ChangeRate.LOW_CHANGE) .dataChangeRateHint(ChangeRate.LOW_CHANGE) .entryCountHint(100) .build(); final StableReadExternalCache<String> cache = vCacheFactory().getStableReadExternalCache( "my-stable-read-cache", StringMarshalling.pair(), settings); assertThat(cache, notNullValue()); assertThat(cache.getName(), is("my-stable-read-cache")); final CompletionStage<Void> rmall = cache.removeAll(); assertThat(rmall, successful()); final CompletionStage<Boolean> put1 = cache.put("three", "drei", PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("three"); assertThat(get1, successfulWith(is(Optional.of("drei")))); assertThat(invocationsOfBegunTxns, is(0)); }
@Test public void getOperation() { final Optional<String> result = fold(offlineCache.get("key"), t -> t, err -> Optional.of("failed")); assertThat(result, is(equalTo(Optional.of("failed")))); }
blockedInFactory.await(); final CompletableFuture<String> t2Result = runAndWaitForStart(() -> cache.get("B", () -> { log.info("{}: About to throw exception", Thread.currentThread().getName()); throw exSingle; assertThat(cache.get("A").toCompletableFuture().join(), is(Optional.empty())); assertThat(cache.get("B").toCompletableFuture().join(), is(Optional.empty())); assertThat(cache.get("C").toCompletableFuture().join(), is(Optional.empty()));
@Test public void stableReadExternalCache_normal_marshaller() { final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder() .defaultTtl(Duration.ofSeconds(60)) .entryGrowthRateHint(ChangeRate.LOW_CHANGE) .dataChangeRateHint(ChangeRate.LOW_CHANGE) .entryCountHint(100) .build(); @SuppressWarnings("deprecation") final StableReadExternalCache<String> cache = vCacheFactory().getStableReadExternalCache( "my-stable-read-cache", MarshallerFactory.stringMarshaller(), settings); assertThat(cache, notNullValue()); assertThat(cache.getName(), is("my-stable-read-cache")); final CompletionStage<Void> rmall = cache.removeAll(); assertThat(rmall, successful()); final CompletionStage<Boolean> put1 = cache.put("three", "drei", PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("three"); assertThat(get1, successfulWith(is(Optional.of("drei")))); assertThat(invocationsOfBegunTxns, is(0)); }
@Test public void getWithSupplierOperation() { final String result = fold(offlineCache.get("key", () -> "value"), t -> t, err -> "failed"); assertThat(result, is(equalTo("failed"))); }
runAndWaitForStart(() -> cache.get("B", () -> "B-2").toCompletableFuture().join()); assertThat(t1ResultData.get("B"), is("B-2")); assertThat(t1ResultData.get("C"), is("C-1")); assertThat(cache.get("A").toCompletableFuture().join(), is(Optional.of("A-1"))); assertThat(cache.get("B").toCompletableFuture().join(), is(Optional.of("B-2"))); assertThat(cache.get("C").toCompletableFuture().join(), is(Optional.of("C-1")));
@Test public void potential_deadlock() { final CompletableFuture<String> get = cache.get("lockType", () -> { // People have actually done this!! cache.remove("lockType"); return "lockwood"; }).toCompletableFuture(); assertThat(get, successfulWith(is("lockwood"))); }
@SuppressWarnings("ConstantConditions") @Test public void check_null_detection() { assertThat(cache.get("kenny", () -> null), not(successful())); assertThat(cache.put("key", null, PutPolicy.ADD_ONLY), not(successful())); assertThat(cache.getBulk( strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> null)), "extra"), not(successful())); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_GET, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FAILED_PUT, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(2L), is(2L))); assertThat(cacheMetrics, hasSize(is(8))); }
public String getEmbedData(String url, Pattern pattern, String cacheName) { final StableReadExternalCache<String> cache = getCache(cacheName); final Optional<String> result = join(cache.get(url)); if (result.isPresent()) return result.get(); HttpResponse response = getResponse(url); String line; try { if (response == null) return null; BufferedReader br = new BufferedReader(new InputStreamReader(response.getResponse())); Matcher m; while ((line = br.readLine()) != null) { m = pattern.matcher(line); if (m.find()) { br.close(); String embedId = m.group(1); join(getCache(cacheName).put(url, embedId, PUT_ALWAYS)); return embedId; } } br.close(); } catch (IOException e) { log.error("An error occured parsing the response from: " + url); } finally { if (response != null) response.finish(); } return null; }
@Test public void dual_cache_get_with_supplier_take2() throws ExecutionException, InterruptedException { final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.empty()))); final CompletionStage<Boolean> dput1 = directCache.put("claira", "singing", PutPolicy.PUT_ALWAYS); assertThat(dput1, successfulWith(is(true))); final CompletionStage<String> get2 = cache.get("claira", () -> "riding"); assertThat(get2, successfulWith(is("singing"))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(3L), is(3L))); assertThat(cacheMetrics, hasSize(is(4))); }
@Test public void single_cache_get_set() throws ExecutionException, InterruptedException { final CompletionStage<Optional<String>> eldestGet = cache.get("claira"); assertThat(eldestGet, successfulWith(is(Optional.empty()))); final CompletionStage<Boolean> eldestAdd = cache.put("claira", "dancing", PutPolicy.ADD_ONLY); assertThat(eldestAdd, successfulWith(is(true))); final CompletionStage<Optional<String>> eldestGet2 = cache.get("claira"); assertThat(eldestGet2, successfulWith(is(Optional.of("dancing")))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Test public void dual_cache_get_with_supplier() throws ExecutionException, InterruptedException { final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.empty()))); final CompletionStage<String> get2 = cache.get("claira", () -> "dancing"); assertThat(get2, successfulWith(is("dancing"))); final CompletionStage<Optional<String>> get3 = cache.get("claira"); assertThat(get3, successfulWith(is(Optional.of("dancing")))); // Change will not be visible to main cache final CompletionStage<Boolean> dput1 = directCache.put("claira", "singing", PutPolicy.PUT_ALWAYS); assertThat(dput1, successfulWith(is(true))); final CompletionStage<Optional<String>> get4 = cache.get("claira"); assertThat(get4, successfulWith(is(Optional.of("dancing")))); final CompletionStage<String> get5 = cache.get("claira", () -> "riding"); assertThat(get5, successfulWith(is("dancing"))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(5L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(3L), is(3L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(2L), is(2L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Nonnull private TweetRetrievalResult getTweetRetrievalResultFromCache(String statusId, Supplier<TweetRetrievalResult> loader) { try { final TweetRetrievalResult result = join(cacheRef.get().get(statusId, loader::get)); if (result.isExpiredFailureResult()) // The cache contains a failure result that has now expired, so remove it removeFromCache(statusId); return result; } catch (ClassCastException | VCacheException pluginUpgraded) { LOG.debug("Removed cached Tweet retrieval result by a previously installed version of the Widget Connector Plugin.", pluginUpgraded); removeFromCache(statusId); return loader.get(); } }
@Test public void dual_cache_get_set() throws ExecutionException, InterruptedException { final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.empty()))); // Change will not be visible to main cache final CompletionStage<Boolean> dput1 = directCache.put("claira", "dancing", PutPolicy.PUT_ALWAYS); assertThat(dput1, successfulWith(is(true))); final CompletionStage<Optional<String>> get2 = cache.get("claira"); assertThat(get2, successfulWith(is(Optional.empty()))); // Add will fail as value exists from the other cache. However, we will now be able to see the // value added by the other cache. final CompletionStage<Boolean> put1 = cache.put("claira", "singing", PutPolicy.ADD_ONLY); assertThat(put1, successfulWith(is(false))); final CompletionStage<Optional<String>> get3 = cache.get("claira"); assertThat(get3, successfulWith(is(Optional.of("dancing")))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(3L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(2L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(2L), is(2L))); assertThat(cacheMetrics, hasSize(is(5))); }
@Test public void simple_removeAll() throws ExecutionException, InterruptedException { final CompletionStage<Boolean> put1 = cache.put("claira", "dancing", PutPolicy.PUT_ALWAYS); assertThat(put1, successfulWith(is(true))); final CompletionStage<Optional<String>> get1 = cache.get("claira"); assertThat(get1, successfulWith(is(Optional.of("dancing")))); final CompletionStage<Void> rm1 = cache.removeAll(); assertThat(rm1, successful()); final CompletionStage<Optional<String>> get2 = cache.get("claira"); assertThat(get2, successfulWith(is(Optional.empty()))); final Map<MetricLabel, ? extends LongMetric> cacheMetrics = requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L))); assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L))); assertThat(cacheMetrics, hasSize(is(6))); }
@Test public void handle_legal_recursive_get_supplier() { final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder() .defaultTtl(Duration.ofSeconds(60)) .entryGrowthRateHint(ChangeRate.LOW_CHANGE) .dataChangeRateHint(ChangeRate.LOW_CHANGE) .entryCountHint(100) .build(); final StableReadExternalCache<String> cache = vCacheFactory().getStableReadExternalCache( "my-stable-read-cache", StringMarshalling.pair(), settings); final CompletionStage<String> get1 = cache.get("recursive", () -> "ignored-" + unsafeJoin(cache.get("recursive", () -> "2"))); assertThat(get1, successfulWith(is("2"))); }
@Test public void handle_legal_recursive_get_supplier2() { final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder() .defaultTtl(Duration.ofSeconds(60)) .entryGrowthRateHint(ChangeRate.LOW_CHANGE) .dataChangeRateHint(ChangeRate.LOW_CHANGE) .entryCountHint(100) .build(); final StableReadExternalCache<String> cache = vCacheFactory().getStableReadExternalCache( "my-stable-read-cache", StringMarshalling.pair(), settings); final CompletionStage<String> get1 = cache.get("recursive", () -> unsafeJoin(cache.get("recursive2", () -> "pass"))); assertThat(get1, successfulWith(is("pass"))); } }
@Test public void stablereadexternalcache_duplicate_obtain() { final StableReadExternalCache<String> firstTime = vCacheFactory().getStableReadExternalCache( "duplicate", dodgyPair("first"), new ExternalCacheSettingsBuilder().build()); final CompletionStage<Boolean> put1 = firstTime.put("key", "ignored", PUT_ALWAYS); assertThat(VCacheUtils.unsafeJoin(put1), is(true)); forceNewRequestContext(); final CompletionStage<Optional<String>> get1 = firstTime.get("key"); assertThat(VCacheUtils.unsafeJoin(get1), is(Optional.of("first"))); final StableReadExternalCache<String> secondTime = vCacheFactory().getStableReadExternalCache( "duplicate", dodgyPair("second"), new ExternalCacheSettingsBuilder().build()); forceNewRequestContext(); final CompletionStage<Optional<String>> get2 = secondTime.get("key"); assertThat(VCacheUtils.unsafeJoin(get2), is(Optional.of("second"))); }