Search in sources :

Example 1 with FederationThrottleException

use of com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException in project aws-athena-query-federation by awslabs.

the class ThrottlingInvokerTest method invokeWithThrottle.

@Test
public void invokeWithThrottle() throws TimeoutException {
    ThrottlingInvoker invoker = ThrottlingInvoker.newBuilder().withDecrease(0.8).withIncrease(1).withInitialDelayMs(10).withMaxDelayMs(200).withFilter((Exception ex) -> ex instanceof FederationThrottleException).build();
    for (int i = 0; i < 5; i++) {
        // Make a call and validate that the state didn't change
        final AtomicLong count = new AtomicLong(0);
        final int val = i;
        long result = invoker.invoke(() -> {
            if (count.incrementAndGet() < 4) {
                throw new FederationThrottleException();
            }
            return val;
        }, 10_000);
        assertEquals(val, result);
        assertEquals(4, count.get());
        assertEquals(ThrottlingInvoker.State.AVOIDANCE, invoker.getState());
        assertTrue(invoker.getDelay() > 0);
    }
    assertEquals(199, invoker.getDelay());
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) FederationThrottleException(com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException) FederationThrottleException(com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Example 2 with FederationThrottleException

use of com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException in project aws-athena-query-federation by awslabs.

the class ExampleRecordHandler method readWithConstraint.

/**
 * Here we generate our simulated row data. A real connector would instead connect to the actual source and read
 * the data corresponding to the requested split.
 *
 * @param spiller A BlockSpiller that should be used to write the row data associated with this Split.
 * The BlockSpiller automatically handles applying constraints, chunking the response, encrypting, and spilling to S3.
 * @param request The ReadRecordsRequest containing the split and other details about what to read.
 * @param queryStatusChecker A QueryStatusChecker that you can use to stop doing work for a query that has already terminated
 */
@Override
protected void readWithConstraint(BlockSpiller spiller, ReadRecordsRequest request, QueryStatusChecker queryStatusChecker) {
    long startTime = System.currentTimeMillis();
    /**
     * It is important to try and throw any throttling events before writing data since Athena may not be able to
     * continue the query, due to consistency errors, if you throttle after writing data.
     */
    if (simulateThrottle > 0 && count++ % simulateThrottle == 0) {
        logger.info("readWithConstraint: throwing throttle Exception!");
        throw new FederationThrottleException("Please slow down for this simulated throttling event");
    }
    logCaller(request);
    Set<String> partitionCols = new HashSet<>();
    String partitionColsMetadata = request.getSchema().getCustomMetadata().get("partitionCols");
    if (partitionColsMetadata != null) {
        partitionCols.addAll(Arrays.asList(partitionColsMetadata.split(",")));
    }
    int year = Integer.valueOf(request.getSplit().getProperty("year"));
    int month = Integer.valueOf(request.getSplit().getProperty("month"));
    int day = Integer.valueOf(request.getSplit().getProperty("day"));
    final RowContext rowContext = new RowContext(year, month, day);
    GeneratedRowWriter.RowWriterBuilder builder = GeneratedRowWriter.newBuilder(request.getConstraints());
    for (Field next : request.getSchema().getFields()) {
        Extractor extractor = makeExtractor(next, rowContext);
        if (extractor != null) {
            builder.withExtractor(next.getName(), extractor);
        } else {
            builder.withFieldWriterFactory(next.getName(), makeFactory(next, rowContext));
        }
    }
    GeneratedRowWriter rowWriter = builder.build();
    for (int i = 0; i < numRowsPerSplit; i++) {
        rowContext.seed = i;
        rowContext.negative = i % 2 == 0;
        if (!queryStatusChecker.isQueryRunning()) {
            return;
        }
        spiller.writeRows((Block block, int rowNum) -> rowWriter.writeRow(block, rowNum, rowContext) ? 1 : 0);
    }
    logger.info("readWithConstraint: Completed generating rows in {} ms", System.currentTimeMillis() - startTime);
}
Also used : Field(org.apache.arrow.vector.types.pojo.Field) GeneratedRowWriter(com.amazonaws.athena.connector.lambda.data.writers.GeneratedRowWriter) Block(com.amazonaws.athena.connector.lambda.data.Block) FederationThrottleException(com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException) BigIntExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.BigIntExtractor) DecimalExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.DecimalExtractor) DateDayExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.DateDayExtractor) TinyIntExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.TinyIntExtractor) VarBinaryExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.VarBinaryExtractor) BitExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.BitExtractor) IntExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.IntExtractor) Extractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.Extractor) Float8Extractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.Float8Extractor) SmallIntExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.SmallIntExtractor) VarCharExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.VarCharExtractor) Float4Extractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.Float4Extractor) DateMilliExtractor(com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor) HashSet(java.util.HashSet)

Example 3 with FederationThrottleException

use of com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException in project aws-athena-query-federation by awslabs.

the class ExampleMetadataHandler method doGetSplits.

/**
 * For each partition we generate a pre-determined number of splits based on the NUM_PARTS_PER_SPLIT setting. This
 * method also demonstrates how to handle calls for batches of partitions and also leverage this API's ability
 * to paginated. A connector for a real data source would likely query that source's metadata to determine if/how
 * to split up the read operations for a particular partition.
 *
 * @param allocator Tool for creating and managing Apache Arrow Blocks.
 * @param request Provides details of the catalog, database, table, andpartition(s) being queried as well as
 * any filter predicate.
 * @return A GetSplitsResponse which contains a list of splits as an optional continuation token if we were not
 * able to generate all splits for the partitions in this batch.
 */
@Override
public GetSplitsResponse doGetSplits(BlockAllocator allocator, GetSplitsRequest request) {
    logCaller(request);
    logger.info("doGetSplits: spill location " + makeSpillLocation(request));
    /**
     * It is important to try and throw any throttling events before writing data since Athena may not be able to
     * continue the query, due to consistency errors, if you throttle after writing data.
     */
    if (simulateThrottle > 0 && count++ % simulateThrottle == 0) {
        logger.info("readWithConstraint: throwing throttle Exception!");
        throw new FederationThrottleException("Please slow down for this simulated throttling event");
    }
    ContinuationToken requestToken = ContinuationToken.decode(request.getContinuationToken());
    int partitionContd = requestToken.getPartition();
    int partContd = requestToken.getPart();
    Set<Split> splits = new HashSet<>();
    Block partitions = request.getPartitions();
    for (int curPartition = partitionContd; curPartition < partitions.getRowCount(); curPartition++) {
        // We use the makeEncryptionKey() method from our parent class to make an EncryptionKey
        EncryptionKey encryptionKey = makeEncryptionKey();
        // We prepare to read our custom metadata fields from the partition so that we can pass this info to the split(s)
        FieldReader locationReader = partitions.getFieldReader(SplitProperties.LOCATION.getId());
        locationReader.setPosition(curPartition);
        FieldReader storageClassReader = partitions.getFieldReader(SplitProperties.SERDE.getId());
        storageClassReader.setPosition(curPartition);
        // table scan operations (aka splits)
        for (int curPart = partContd; curPart < NUM_PARTS_PER_SPLIT; curPart++) {
            if (splits.size() >= MAX_SPLITS_PER_REQUEST) {
                // a continuation token.
                return new GetSplitsResponse(request.getCatalogName(), splits, ContinuationToken.encode(curPartition, curPart));
            }
            // We use makeSpillLocation(...) from our parent class to get a unique SpillLocation for each split
            Split.Builder splitBuilder = Split.newBuilder(makeSpillLocation(request), encryptionEnabled ? encryptionKey : null).add(SplitProperties.LOCATION.getId(), String.valueOf(locationReader.readText())).add(SplitProperties.SERDE.getId(), String.valueOf(storageClassReader.readText())).add(SplitProperties.SPLIT_PART.getId(), String.valueOf(curPart));
            // will likely vary. Our example only supports a limited number of partition column types.
            for (String next : request.getPartitionCols()) {
                FieldReader reader = partitions.getFieldReader(next);
                reader.setPosition(curPartition);
                switch(reader.getMinorType()) {
                    case UINT2:
                        splitBuilder.add(next, Integer.valueOf(reader.readCharacter()).toString());
                        break;
                    case UINT4:
                    case INT:
                        splitBuilder.add(next, String.valueOf(reader.readInteger()));
                        break;
                    case UINT8:
                    case BIGINT:
                        splitBuilder.add(next, String.valueOf(reader.readLong()));
                        break;
                    default:
                        throw new RuntimeException("Unsupported partition column type. " + reader.getMinorType());
                }
            }
            splits.add(splitBuilder.build());
        }
        // part continuation only applies within a partition so we complete that partial partition and move on
        // to the next one.
        partContd = 0;
    }
    return new GetSplitsResponse(request.getCatalogName(), splits, null);
}
Also used : EncryptionKey(com.amazonaws.athena.connector.lambda.security.EncryptionKey) GetSplitsResponse(com.amazonaws.athena.connector.lambda.metadata.GetSplitsResponse) Block(com.amazonaws.athena.connector.lambda.data.Block) FederationThrottleException(com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException) Split(com.amazonaws.athena.connector.lambda.domain.Split) FieldReader(org.apache.arrow.vector.complex.reader.FieldReader) HashSet(java.util.HashSet)

Aggregations

FederationThrottleException (com.amazonaws.athena.connector.lambda.exceptions.FederationThrottleException)3 Block (com.amazonaws.athena.connector.lambda.data.Block)2 HashSet (java.util.HashSet)2 GeneratedRowWriter (com.amazonaws.athena.connector.lambda.data.writers.GeneratedRowWriter)1 BigIntExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.BigIntExtractor)1 BitExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.BitExtractor)1 DateDayExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.DateDayExtractor)1 DateMilliExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor)1 DecimalExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.DecimalExtractor)1 Extractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.Extractor)1 Float4Extractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.Float4Extractor)1 Float8Extractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.Float8Extractor)1 IntExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.IntExtractor)1 SmallIntExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.SmallIntExtractor)1 TinyIntExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.TinyIntExtractor)1 VarBinaryExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.VarBinaryExtractor)1 VarCharExtractor (com.amazonaws.athena.connector.lambda.data.writers.extractors.VarCharExtractor)1 Split (com.amazonaws.athena.connector.lambda.domain.Split)1 GetSplitsResponse (com.amazonaws.athena.connector.lambda.metadata.GetSplitsResponse)1 EncryptionKey (com.amazonaws.athena.connector.lambda.security.EncryptionKey)1