use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.
the class CachingTableProvider method createDefaultCacheTable.
private ReadWriteUpdateTable createDefaultCacheTable(String tableId, JavaTableConfig tableConfig) {
long readTtlMs = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.READ_TTL_MS, "-1"));
long writeTtlMs = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.WRITE_TTL_MS, "-1"));
long cacheSize = Long.parseLong(tableConfig.getForTable(tableId, CachingTableDescriptor.CACHE_SIZE, "-1"));
CacheBuilder cacheBuilder = CacheBuilder.newBuilder();
if (readTtlMs != -1) {
cacheBuilder.expireAfterAccess(readTtlMs, TimeUnit.MILLISECONDS);
}
if (writeTtlMs != -1) {
cacheBuilder.expireAfterWrite(writeTtlMs, TimeUnit.MILLISECONDS);
}
if (cacheSize != -1) {
cacheBuilder.maximumSize(cacheSize);
}
logger.info(String.format("Creating default cache with: readTtl=%d, writeTtl=%d, maxSize=%d", readTtlMs, writeTtlMs, cacheSize));
GuavaCacheTable cacheTable = new GuavaCacheTable(tableId + "-def-cache", cacheBuilder.build());
cacheTable.init(this.context);
return cacheTable;
}
use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.
the class TestCachingTable method testTimerDisabled.
@Test
public void testTimerDisabled() throws Exception {
String tableId = "testTimerDisabled";
Cache<String, String> guavaCache = CacheBuilder.newBuilder().initialCapacity(100).build();
final ReadWriteUpdateTable<String, String, String> guavaTable = new GuavaCacheTable<>(tableId, guavaCache);
TableRateLimiter<String, String> readRateLimitHelper = mock(TableRateLimiter.class);
TableRateLimiter<String, String> writeRateLimitHelper = mock(TableRateLimiter.class);
TableRateLimiter<String, String> updateRateLimitHelper = mock(TableRateLimiter.class);
TableReadFunction<String, String> readFn = mock(TableReadFunction.class);
doReturn(CompletableFuture.completedFuture("")).when(readFn).getAsync(any());
TableWriteFunction<String, String, String> writeFn = mock(TableWriteFunction.class);
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAsync(any(), any());
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAsync(any());
final RemoteTable<String, String, String> remoteTable = new RemoteTable<>(tableId, readFn, writeFn, readRateLimitHelper, writeRateLimitHelper, updateRateLimitHelper, Executors.newSingleThreadExecutor(), null, null, null, null, null, Executors.newSingleThreadExecutor());
final CachingTable<String, String, String> cachingTable = new CachingTable<>(tableId, remoteTable, guavaTable, false);
initTables(true, cachingTable, guavaTable, remoteTable);
cachingTable.get("");
cachingTable.getAsync("").get();
cachingTable.getAll(Collections.emptyList());
cachingTable.getAllAsync(Collections.emptyList());
cachingTable.flush();
cachingTable.put("", "");
cachingTable.putAsync("", "");
cachingTable.putAll(Collections.emptyList());
cachingTable.putAllAsync(Collections.emptyList());
cachingTable.delete("");
cachingTable.deleteAsync("");
cachingTable.deleteAll(Collections.emptyList());
cachingTable.deleteAllAsync(Collections.emptyList());
}
use of org.apache.samza.table.caching.guava.GuavaCacheTable in project samza by apache.
the class TestCachingTable method testGuavaCacheAndRemoteTable.
/**
* Testing caching in a more realistic scenario with Guava cache + remote table
*/
@Test
public void testGuavaCacheAndRemoteTable() throws Exception {
String tableId = "testGuavaCacheAndRemoteTable";
Cache<String, String> guavaCache = CacheBuilder.newBuilder().initialCapacity(100).build();
final ReadWriteUpdateTable<String, String, String> guavaTable = new GuavaCacheTable<>(tableId + "-cache", guavaCache);
// It is okay to share rateLimitHelper and async helper for read/write in test
TableRateLimiter<String, String> readRateLimitHelper = mock(TableRateLimiter.class);
TableRateLimiter<String, String> writeRateLimitHelper = mock(TableRateLimiter.class);
TableRateLimiter<String, String> updateRateLimitHelper = mock(TableRateLimiter.class);
TableReadFunction<String, String> readFn = mock(TableReadFunction.class);
TableWriteFunction<String, String, String> writeFn = mock(TableWriteFunction.class);
final RemoteTable<String, String, String> remoteTable = new RemoteTable<>(tableId + "-remote", readFn, writeFn, readRateLimitHelper, writeRateLimitHelper, updateRateLimitHelper, Executors.newSingleThreadExecutor(), null, null, null, null, null, Executors.newSingleThreadExecutor());
final CachingTable<String, String, String> cachingTable = new CachingTable<>(tableId, remoteTable, guavaTable, false);
initTables(cachingTable, guavaTable, remoteTable);
// 4 per readable table (12)
// 8 per read/write table (24)
verify(metricsRegistry, times(36)).newCounter(any(), anyString());
// 3 per readable table (9)
// 8 per read/write table (24)
// 1 per remote readable table (1)
// 2 per remote read/write table (2)
verify(metricsRegistry, times(36)).newTimer(any(), anyString());
// 1 per guava table (1)
// 3 per caching table (2)
verify(metricsRegistry, times(4)).newGauge(anyString(), any());
// GET
doReturn(CompletableFuture.completedFuture("bar")).when(readFn).getAsync(any());
Assert.assertEquals(cachingTable.getAsync("foo").get(), "bar");
// Ensure cache is updated
Assert.assertEquals(guavaCache.getIfPresent("foo"), "bar");
// PUT
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAsync(any(), any());
cachingTable.putAsync("foo", "baz").get();
// Ensure cache is updated
Assert.assertEquals(guavaCache.getIfPresent("foo"), "baz");
// DELETE
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAsync(any());
cachingTable.deleteAsync("foo").get();
// Ensure cache is updated
Assert.assertNull(guavaCache.getIfPresent("foo"));
// GET-ALL
Map<String, String> records = new HashMap<>();
records.put("foo1", "bar1");
records.put("foo2", "bar2");
doReturn(CompletableFuture.completedFuture(records)).when(readFn).getAllAsync(any());
Assert.assertEquals(cachingTable.getAllAsync(Arrays.asList("foo1", "foo2")).get(), records);
// Ensure cache is updated
Assert.assertEquals(guavaCache.getIfPresent("foo1"), "bar1");
Assert.assertEquals(guavaCache.getIfPresent("foo2"), "bar2");
// GET-ALL with partial miss
doReturn(CompletableFuture.completedFuture(Collections.singletonMap("foo3", "bar3"))).when(readFn).getAllAsync(any());
records = cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo3")).get();
Assert.assertEquals(records.get("foo3"), "bar3");
// Ensure cache is updated
Assert.assertEquals(guavaCache.getIfPresent("foo3"), "bar3");
// Calling again for the same keys should not trigger IO, ie. no exception is thrown
CompletableFuture<String> exFuture = new CompletableFuture<>();
exFuture.completeExceptionally(new RuntimeException("Test exception"));
doReturn(exFuture).when(readFn).getAllAsync(any());
cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo3")).get();
// Partial results should throw
try {
cachingTable.getAllAsync(Arrays.asList("foo1", "foo2", "foo5")).get();
Assert.fail();
} catch (Exception e) {
}
// PUT-ALL
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAllAsync(any());
List<Entry<String, String>> entries = new ArrayList<>();
entries.add(new Entry<>("foo1", "bar111"));
entries.add(new Entry<>("foo2", "bar222"));
cachingTable.putAllAsync(entries).get();
// Ensure cache is updated
Assert.assertEquals(guavaCache.getIfPresent("foo1"), "bar111");
Assert.assertEquals(guavaCache.getIfPresent("foo2"), "bar222");
// PUT-ALL with delete
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).putAllAsync(any());
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAllAsync(any());
entries = new ArrayList<>();
entries.add(new Entry<>("foo1", "bar111"));
entries.add(new Entry<>("foo2", null));
cachingTable.putAllAsync(entries).get();
// Ensure cache is updated
Assert.assertNull(guavaCache.getIfPresent("foo2"));
// At this point, foo1 and foo3 should still exist
Assert.assertNotNull(guavaCache.getIfPresent("foo1"));
Assert.assertNotNull(guavaCache.getIfPresent("foo3"));
// DELETE-ALL
doReturn(CompletableFuture.completedFuture(null)).when(writeFn).deleteAllAsync(any());
cachingTable.deleteAllAsync(Arrays.asList("foo1", "foo3")).get();
// Ensure foo1 and foo3 are gone
Assert.assertNull(guavaCache.getIfPresent("foo1"));
Assert.assertNull(guavaCache.getIfPresent("foo3"));
}
Aggregations