Search in sources :

Example 6 with ReadWriteUpdateTable

use of org.apache.samza.table.ReadWriteUpdateTable in project samza by apache.

the class TestCachingTable method doTestCacheOps.

private void doTestCacheOps(boolean isWriteAround) {
    CachingTableDescriptor desc = new CachingTableDescriptor("1", createDummyTableDescriptor("realTable"), createDummyTableDescriptor("cacheTable"));
    if (isWriteAround) {
        desc.withWriteAround();
    }
    Context context = new MockContext();
    final ReadWriteUpdateTable cacheTable = getMockCache().getLeft();
    final ReadWriteUpdateTable realTable = mock(ReadWriteUpdateTable.class);
    doAnswer(invocation -> {
        String key = invocation.getArgumentAt(0, String.class);
        return CompletableFuture.completedFuture("test-data-" + key);
    }).when(realTable).getAsync(any());
    doReturn(CompletableFuture.completedFuture(null)).when(realTable).putAsync(any(), any());
    doAnswer(invocation -> {
        String tableId = invocation.getArgumentAt(0, String.class);
        if (tableId.equals("realTable")) {
            // cache
            return realTable;
        } else if (tableId.equals("cacheTable")) {
            return cacheTable;
        }
        Assert.fail();
        return null;
    }).when(context.getTaskContext()).getUpdatableTable(anyString());
    when(context.getContainerContext().getContainerMetricsRegistry()).thenReturn(new NoOpMetricsRegistry());
    Map<String, String> tableConfig = desc.toConfig(new MapConfig());
    when(context.getJobContext().getConfig()).thenReturn(new MapConfig(tableConfig));
    CachingTableProvider tableProvider = new CachingTableProvider(desc.getTableId());
    tableProvider.init(context);
    CachingTable cachingTable = (CachingTable) tableProvider.getTable();
    Assert.assertEquals("test-data-1", cachingTable.get("1"));
    verify(realTable, times(1)).getAsync(any());
    // cache miss
    verify(cacheTable, times(1)).get(any());
    verify(cacheTable, times(1)).put(any(), any());
    // 0 hit, 1 request
    Assert.assertEquals(cachingTable.hitRate(), 0.0, 0.0);
    Assert.assertEquals(cachingTable.missRate(), 1.0, 0.0);
    Assert.assertEquals("test-data-1", cachingTable.get("1"));
    // no change
    verify(realTable, times(1)).getAsync(any());
    verify(cacheTable, times(2)).get(any());
    // no change
    verify(cacheTable, times(1)).put(any(), any());
    // 1 hit, 2 requests
    Assert.assertEquals(0.5, cachingTable.hitRate(), 0.0);
    Assert.assertEquals(0.5, cachingTable.missRate(), 0.0);
    cachingTable.put("2", "test-data-XXXX");
    verify(cacheTable, times(isWriteAround ? 1 : 2)).put(any(), any());
    verify(realTable, times(1)).putAsync(any(), any());
    if (isWriteAround) {
        // expects value from table
        Assert.assertEquals("test-data-2", cachingTable.get("2"));
        // should have one more fetch
        verify(realTable, times(2)).getAsync(any());
        // 1 hit, 3 requests
        Assert.assertEquals(cachingTable.hitRate(), 0.33, 0.1);
    } else {
        // expect value from cache
        Assert.assertEquals("test-data-XXXX", cachingTable.get("2"));
        // no change
        verify(realTable, times(1)).getAsync(any());
        // 2 hits, 3 requests
        Assert.assertEquals(cachingTable.hitRate(), 0.66, 0.1);
    }
}
Also used : MockContext(org.apache.samza.context.MockContext) Context(org.apache.samza.context.Context) ReadWriteUpdateTable(org.apache.samza.table.ReadWriteUpdateTable) MockContext(org.apache.samza.context.MockContext) NoOpMetricsRegistry(org.apache.samza.util.NoOpMetricsRegistry) CachingTableDescriptor(org.apache.samza.table.descriptors.CachingTableDescriptor) Matchers.anyString(org.mockito.Matchers.anyString) MapConfig(org.apache.samza.config.MapConfig)

Example 7 with ReadWriteUpdateTable

use of org.apache.samza.table.ReadWriteUpdateTable in project samza by apache.

the class TestStreamTableJoinOperatorImpl method testHandleMessage.

@Test
public void testHandleMessage() {
    String tableId = "t1";
    StreamTableJoinOperatorSpec mockJoinOpSpec = mock(StreamTableJoinOperatorSpec.class);
    when(mockJoinOpSpec.getTableId()).thenReturn(tableId);
    when(mockJoinOpSpec.getArgs()).thenReturn(new Object[0]);
    when(mockJoinOpSpec.getJoinFn()).thenReturn(new StreamTableJoinFunction<String, KV<String, String>, KV<String, String>, String>() {

        @Override
        public String apply(KV<String, String> message, KV<String, String> record) {
            if ("1".equals(message.getKey())) {
                Assert.assertEquals("m1", message.getValue());
                Assert.assertEquals("r1", record.getValue());
                return "m1r1";
            } else if ("2".equals(message.getKey())) {
                Assert.assertEquals("m2", message.getValue());
                Assert.assertNull(record);
                return null;
            }
            throw new SamzaException("Should never reach here!");
        }

        @Override
        public String getMessageKey(KV<String, String> message) {
            return message.getKey();
        }

        @Override
        public String getRecordKey(KV<String, String> record) {
            return record.getKey();
        }
    });
    ReadWriteUpdateTable table = mock(ReadWriteUpdateTable.class);
    when(table.getAsync("1")).thenReturn(CompletableFuture.completedFuture("r1"));
    when(table.getAsync("2")).thenReturn(CompletableFuture.completedFuture(null));
    Context context = new MockContext();
    when(context.getTaskContext().getUpdatableTable(tableId)).thenReturn(table);
    MessageCollector mockMessageCollector = mock(MessageCollector.class);
    TaskCoordinator mockTaskCoordinator = mock(TaskCoordinator.class);
    StreamTableJoinOperatorImpl streamTableJoinOperator = new StreamTableJoinOperatorImpl(mockJoinOpSpec, context);
    // Table has the key
    Collection<TestMessageEnvelope> result;
    result = streamTableJoinOperator.handleMessage(KV.of("1", "m1"), mockMessageCollector, mockTaskCoordinator);
    Assert.assertEquals(1, result.size());
    Assert.assertEquals("m1r1", result.iterator().next());
    // Table doesn't have the key
    result = streamTableJoinOperator.handleMessage(KV.of("2", "m2"), mockMessageCollector, mockTaskCoordinator);
    Assert.assertEquals(0, result.size());
}
Also used : Context(org.apache.samza.context.Context) MockContext(org.apache.samza.context.MockContext) ReadWriteUpdateTable(org.apache.samza.table.ReadWriteUpdateTable) MockContext(org.apache.samza.context.MockContext) TaskCoordinator(org.apache.samza.task.TaskCoordinator) KV(org.apache.samza.operators.KV) SamzaException(org.apache.samza.SamzaException) TestMessageEnvelope(org.apache.samza.operators.data.TestMessageEnvelope) MessageCollector(org.apache.samza.task.MessageCollector) StreamTableJoinOperatorSpec(org.apache.samza.operators.spec.StreamTableJoinOperatorSpec) Test(org.junit.Test)

Example 8 with ReadWriteUpdateTable

use of org.apache.samza.table.ReadWriteUpdateTable in project samza by apache.

the class TestLocalTableRead method testTimerDisabled.

@Test
public void testTimerDisabled() throws Exception {
    ReadWriteUpdateTable table = createTable(true);
    table.get("");
    table.getAsync("").get();
    table.getAll(keys);
    table.getAllAsync(keys).get();
    Assert.assertEquals(2, numGets.getCount());
    Assert.assertEquals(4, numMissedLookups.getCount());
    Assert.assertEquals(2, numGetAlls.getCount());
    Assert.assertEquals(0, getNs.getSnapshot().getAverage(), 0.001);
    Assert.assertEquals(0, getAllNs.getSnapshot().getAverage(), 0.001);
    Assert.assertEquals(0, getCallbackNs.getSnapshot().getAverage(), 0.001);
}
Also used : ReadWriteUpdateTable(org.apache.samza.table.ReadWriteUpdateTable) Test(org.junit.Test)

Example 9 with ReadWriteUpdateTable

use of org.apache.samza.table.ReadWriteUpdateTable in project samza by apache.

the class RemoteTableProvider method getTable.

@Override
public ReadWriteUpdateTable getTable() {
    Preconditions.checkNotNull(context, String.format("Table %s not initialized", tableId));
    JavaTableConfig tableConfig = new JavaTableConfig(context.getJobContext().getConfig());
    // Read part
    TableReadFunction readFn = deserializeObject(tableConfig, RemoteTableDescriptor.READ_FN);
    RateLimiter rateLimiter = deserializeObject(tableConfig, RemoteTableDescriptor.RATE_LIMITER);
    if (rateLimiter != null) {
        rateLimiter.init(this.context);
    }
    TableRateLimiter.CreditFunction<?, ?> readCreditFn = deserializeObject(tableConfig, RemoteTableDescriptor.READ_CREDIT_FN);
    TableRateLimiter readRateLimiter = rateLimiter != null && rateLimiter.getSupportedTags().contains(RemoteTableDescriptor.RL_READ_TAG) ? new TableRateLimiter(tableId, rateLimiter, readCreditFn, RemoteTableDescriptor.RL_READ_TAG) : null;
    TableRetryPolicy readRetryPolicy = deserializeObject(tableConfig, RemoteTableDescriptor.READ_RETRY_POLICY);
    // Write part
    // Reuse write rate limiter for update
    TableRateLimiter writeRateLimiter = null;
    TableRetryPolicy writeRetryPolicy = null;
    TableWriteFunction writeFn = deserializeObject(tableConfig, RemoteTableDescriptor.WRITE_FN);
    if (writeFn != null) {
        TableRateLimiter.CreditFunction<?, ?> writeCreditFn = deserializeObject(tableConfig, RemoteTableDescriptor.WRITE_CREDIT_FN);
        writeRateLimiter = rateLimiter != null && rateLimiter.getSupportedTags().contains(RemoteTableDescriptor.RL_WRITE_TAG) ? new TableRateLimiter(tableId, rateLimiter, writeCreditFn, RemoteTableDescriptor.RL_WRITE_TAG) : null;
        writeRetryPolicy = deserializeObject(tableConfig, RemoteTableDescriptor.WRITE_RETRY_POLICY);
    }
    if (readRetryPolicy != null || writeRetryPolicy != null) {
        retryExecutor = createRetryExecutor();
    }
    // Optional executor for future callback/completion. Shared by both read and write operations.
    int callbackPoolSize = Integer.parseInt(tableConfig.getForTable(tableId, RemoteTableDescriptor.ASYNC_CALLBACK_POOL_SIZE, "-1"));
    if (callbackPoolSize > 0) {
        callbackExecutors.computeIfAbsent(tableId, (arg) -> Executors.newFixedThreadPool(callbackPoolSize, (runnable) -> {
            Thread thread = new Thread(runnable);
            thread.setName("table-" + tableId + "-async-callback-pool");
            thread.setDaemon(true);
            return thread;
        }));
    }
    boolean isRateLimited = readRateLimiter != null || writeRateLimiter != null;
    if (isRateLimited) {
        rateLimitingExecutors.computeIfAbsent(tableId, (arg) -> Executors.newSingleThreadExecutor(runnable -> {
            Thread thread = new Thread(runnable);
            thread.setName("table-" + tableId + "-async-executor");
            thread.setDaemon(true);
            return thread;
        }));
    }
    BatchProvider batchProvider = deserializeObject(tableConfig, RemoteTableDescriptor.BATCH_PROVIDER);
    if (batchProvider != null) {
        batchExecutors.computeIfAbsent(tableId, (arg) -> Executors.newSingleThreadScheduledExecutor(runnable -> {
            Thread thread = new Thread(runnable);
            thread.setName("table-" + tableId + "-batch-scheduled-executor");
            thread.setDaemon(true);
            return thread;
        }));
    }
    RemoteTable table = new RemoteTable(tableId, readFn, writeFn, readRateLimiter, writeRateLimiter, writeRateLimiter, rateLimitingExecutors.get(tableId), readRetryPolicy, writeRetryPolicy, retryExecutor, batchProvider, batchExecutors.get(tableId), callbackExecutors.get(tableId));
    table.init(this.context);
    tables.add(table);
    return table;
}
Also used : BatchProvider(org.apache.samza.table.batching.BatchProvider) SerdeUtils(org.apache.samza.table.utils.SerdeUtils) TableRetryPolicy(org.apache.samza.table.retry.TableRetryPolicy) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) JavaTableConfig(org.apache.samza.config.JavaTableConfig) Executors(java.util.concurrent.Executors) ArrayList(java.util.ArrayList) List(java.util.List) ReadWriteUpdateTable(org.apache.samza.table.ReadWriteUpdateTable) BaseTableProvider(org.apache.samza.table.BaseTableProvider) RateLimiter(org.apache.samza.util.RateLimiter) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Preconditions(com.google.common.base.Preconditions) RemoteTableDescriptor(org.apache.samza.table.descriptors.RemoteTableDescriptor) ExecutorService(java.util.concurrent.ExecutorService) BatchProvider(org.apache.samza.table.batching.BatchProvider) TableRetryPolicy(org.apache.samza.table.retry.TableRetryPolicy) RateLimiter(org.apache.samza.util.RateLimiter) JavaTableConfig(org.apache.samza.config.JavaTableConfig)

Example 10 with ReadWriteUpdateTable

use of org.apache.samza.table.ReadWriteUpdateTable in project samza by apache.

the class TestStreamTableJoinOperatorImpl method testJoinFunctionIsInvokedOnlyOnce.

/**
 * Ensure join function is not invoked more than once when join function returns null on the first invocation
 */
@Test
public void testJoinFunctionIsInvokedOnlyOnce() {
    final String tableId = "testTable";
    final CountDownLatch joinInvokedLatch = new CountDownLatch(1);
    StreamTableJoinOperatorSpec mockJoinOpSpec = mock(StreamTableJoinOperatorSpec.class);
    when(mockJoinOpSpec.getTableId()).thenReturn(tableId);
    when(mockJoinOpSpec.getArgs()).thenReturn(new Object[0]);
    when(mockJoinOpSpec.getJoinFn()).thenReturn(new StreamTableJoinFunction<String, KV<String, String>, KV<String, String>, String>() {

        @Override
        public String apply(KV<String, String> message, KV<String, String> record) {
            joinInvokedLatch.countDown();
            return null;
        }

        @Override
        public String getMessageKey(KV<String, String> message) {
            return message.getKey();
        }

        @Override
        public String getRecordKey(KV<String, String> record) {
            return record.getKey();
        }
    });
    ReadWriteUpdateTable table = mock(ReadWriteUpdateTable.class);
    when(table.getAsync("1")).thenReturn(CompletableFuture.completedFuture("r1"));
    Context context = new MockContext();
    when(context.getTaskContext().getUpdatableTable(tableId)).thenReturn(table);
    MessageCollector mockMessageCollector = mock(MessageCollector.class);
    TaskCoordinator mockTaskCoordinator = mock(TaskCoordinator.class);
    StreamTableJoinOperatorImpl streamTableJoinOperator = new StreamTableJoinOperatorImpl(mockJoinOpSpec, context);
    // Table has the key
    streamTableJoinOperator.handleMessage(KV.of("1", "m1"), mockMessageCollector, mockTaskCoordinator);
    assertEquals("Join function should only be invoked once", 0, joinInvokedLatch.getCount());
}
Also used : Context(org.apache.samza.context.Context) MockContext(org.apache.samza.context.MockContext) ReadWriteUpdateTable(org.apache.samza.table.ReadWriteUpdateTable) MockContext(org.apache.samza.context.MockContext) TaskCoordinator(org.apache.samza.task.TaskCoordinator) KV(org.apache.samza.operators.KV) CountDownLatch(java.util.concurrent.CountDownLatch) MessageCollector(org.apache.samza.task.MessageCollector) StreamTableJoinOperatorSpec(org.apache.samza.operators.spec.StreamTableJoinOperatorSpec) Test(org.junit.Test)

Aggregations

ReadWriteUpdateTable (org.apache.samza.table.ReadWriteUpdateTable)16 Test (org.junit.Test)11 Context (org.apache.samza.context.Context)3 MockContext (org.apache.samza.context.MockContext)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 JavaTableConfig (org.apache.samza.config.JavaTableConfig)2 KV (org.apache.samza.operators.KV)2 StreamTableJoinOperatorSpec (org.apache.samza.operators.spec.StreamTableJoinOperatorSpec)2 MessageCollector (org.apache.samza.task.MessageCollector)2 TaskCoordinator (org.apache.samza.task.TaskCoordinator)2 Matchers.anyString (org.mockito.Matchers.anyString)2 Preconditions (com.google.common.base.Preconditions)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 SamzaException (org.apache.samza.SamzaException)1