Search in sources :

Example 1 with VersionedDynamicFilterDomains

use of io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains in project trino by trinodb.

the class HttpRemoteTask method sendUpdate.

private synchronized void sendUpdate() {
    TaskStatus taskStatus = getTaskStatus();
    // don't update if the task hasn't been started yet or if it is already finished
    if (!started.get() || !needsUpdate.get() || taskStatus.getState().isDone()) {
        return;
    }
    // currentRequest is always cleared when request is complete
    if (currentRequest != null) {
        return;
    }
    // if throttled due to error, asynchronously wait for timeout and try again
    ListenableFuture<Void> errorRateLimit = updateErrorTracker.acquireRequestPermit();
    if (!errorRateLimit.isDone()) {
        errorRateLimit.addListener(this::sendUpdate, executor);
        return;
    }
    List<SplitAssignment> splitAssignments = getSplitAssignments();
    VersionedDynamicFilterDomains dynamicFilterDomains = outboundDynamicFiltersCollector.acknowledgeAndGetNewDomains(sentDynamicFiltersVersion);
    // Workers don't need the embedded JSON representation when the fragment is sent
    Optional<PlanFragment> fragment = sendPlan.get() ? Optional.of(planFragment.withoutEmbeddedJsonRepresentation()) : Optional.empty();
    TaskUpdateRequest updateRequest = new TaskUpdateRequest(session.toSessionRepresentation(), session.getIdentity().getExtraCredentials(), fragment, splitAssignments, outputBuffers.get(), dynamicFilterDomains.getDynamicFilterDomains());
    byte[] taskUpdateRequestJson = taskUpdateRequestCodec.toJsonBytes(updateRequest);
    if (fragment.isPresent()) {
        stats.updateWithPlanBytes(taskUpdateRequestJson.length);
    }
    if (!dynamicFilterDomains.getDynamicFilterDomains().isEmpty()) {
        stats.updateWithDynamicFilterBytes(taskUpdateRequestJson.length);
    }
    HttpUriBuilder uriBuilder = getHttpUriBuilder(taskStatus);
    Request request = preparePost().setUri(uriBuilder.build()).setHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()).setBodyGenerator(createStaticBodyGenerator(taskUpdateRequestJson)).build();
    updateErrorTracker.startRequest();
    ListenableFuture<JsonResponse<TaskInfo>> future = httpClient.executeAsync(request, createFullJsonResponseHandler(taskInfoCodec));
    currentRequest = future;
    currentRequestStartNanos = System.nanoTime();
    // The needsUpdate flag needs to be set to false BEFORE adding the Future callback since callback might change the flag value
    // and does so without grabbing the instance lock.
    needsUpdate.set(false);
    Futures.addCallback(future, new SimpleHttpResponseHandler<>(new UpdateResponseHandler(splitAssignments, dynamicFilterDomains.getVersion()), request.getUri(), stats), executor);
}
Also used : TaskUpdateRequest(io.trino.server.TaskUpdateRequest) TaskUpdateRequest(io.trino.server.TaskUpdateRequest) FailTaskRequest(io.trino.server.FailTaskRequest) Request(io.airlift.http.client.Request) SplitAssignment(io.trino.execution.SplitAssignment) TaskStatus(io.trino.execution.TaskStatus) PlanFragment(io.trino.sql.planner.PlanFragment) JsonResponse(io.airlift.http.client.FullJsonResponseHandler.JsonResponse) VersionedDynamicFilterDomains(io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains) HttpUriBuilder(io.airlift.http.client.HttpUriBuilder)

Example 2 with VersionedDynamicFilterDomains

use of io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains in project trino by trinodb.

the class TestDynamicFiltersCollector method testDynamicFiltersCollector.

@Test
public void testDynamicFiltersCollector() {
    DynamicFilterId filter = new DynamicFilterId("filter");
    DynamicFiltersCollector collector = new DynamicFiltersCollector(() -> {
    });
    VersionedDynamicFilterDomains domains = collector.acknowledgeAndGetNewDomains(INITIAL_DYNAMIC_FILTERS_VERSION);
    // there should be no domains initially
    assertEquals(domains.getVersion(), INITIAL_DYNAMIC_FILTERS_VERSION);
    assertEquals(domains.getDynamicFilterDomains(), ImmutableMap.of());
    Domain initialDomain = multipleValues(BIGINT, ImmutableList.of(1L, 2L, 3L));
    collector.updateDomains(ImmutableMap.of(filter, initialDomain));
    domains = collector.acknowledgeAndGetNewDomains(INITIAL_DYNAMIC_FILTERS_VERSION);
    assertEquals(domains.getVersion(), 1L);
    assertEquals(domains.getDynamicFilterDomains(), ImmutableMap.of(filter, initialDomain));
    // make sure domains are still available when requested again with old version
    domains = collector.acknowledgeAndGetNewDomains(INITIAL_DYNAMIC_FILTERS_VERSION);
    assertEquals(domains.getVersion(), 1L);
    assertEquals(domains.getDynamicFilterDomains(), ImmutableMap.of(filter, initialDomain));
    // make sure domains are intersected
    collector.updateDomains(ImmutableMap.of(filter, multipleValues(BIGINT, ImmutableList.of(2L))));
    collector.updateDomains(ImmutableMap.of(filter, multipleValues(BIGINT, ImmutableList.of(3L, 4L))));
    domains = collector.acknowledgeAndGetNewDomains(1L);
    assertEquals(domains.getVersion(), 3L);
    assertEquals(domains.getDynamicFilterDomains(), ImmutableMap.of(filter, Domain.none(BIGINT)));
    // make sure old domains are removed
    DynamicFilterId filter2 = new DynamicFilterId("filter2");
    collector.updateDomains(ImmutableMap.of(filter2, singleValue(BIGINT, 1L)));
    domains = collector.acknowledgeAndGetNewDomains(3L);
    assertEquals(domains.getVersion(), 4L);
    assertEquals(domains.getDynamicFilterDomains(), ImmutableMap.of(filter2, singleValue(BIGINT, 1L)));
}
Also used : Domain(io.trino.spi.predicate.Domain) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) VersionedDynamicFilterDomains(io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains) Test(org.testng.annotations.Test)

Example 3 with VersionedDynamicFilterDomains

use of io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains in project trino by trinodb.

the class TestHttpRemoteTask method testDynamicFilters.

@Test(timeOut = 30000)
public void testDynamicFilters() throws Exception {
    DynamicFilterId filterId1 = new DynamicFilterId("df1");
    DynamicFilterId filterId2 = new DynamicFilterId("df2");
    SymbolAllocator symbolAllocator = new SymbolAllocator();
    Symbol symbol1 = symbolAllocator.newSymbol("DF_SYMBOL1", BIGINT);
    Symbol symbol2 = symbolAllocator.newSymbol("DF_SYMBOL2", BIGINT);
    SymbolReference df1 = symbol1.toSymbolReference();
    SymbolReference df2 = symbol2.toSymbolReference();
    ColumnHandle handle1 = new TestingColumnHandle("column1");
    ColumnHandle handle2 = new TestingColumnHandle("column2");
    QueryId queryId = new QueryId("test");
    TestingTaskResource testingTaskResource = new TestingTaskResource(new AtomicLong(System.nanoTime()), FailureScenario.NO_FAILURE);
    DynamicFilterService dynamicFilterService = new DynamicFilterService(PLANNER_CONTEXT.getMetadata(), PLANNER_CONTEXT.getFunctionManager(), new TypeOperators(), newDirectExecutorService());
    HttpRemoteTaskFactory httpRemoteTaskFactory = createHttpRemoteTaskFactory(testingTaskResource, dynamicFilterService);
    RemoteTask remoteTask = createRemoteTask(httpRemoteTaskFactory, ImmutableSet.of());
    Map<DynamicFilterId, Domain> initialDomain = ImmutableMap.of(filterId1, Domain.singleValue(BIGINT, 1L));
    testingTaskResource.setInitialTaskInfo(remoteTask.getTaskInfo());
    testingTaskResource.setDynamicFilterDomains(new VersionedDynamicFilterDomains(1L, initialDomain));
    dynamicFilterService.registerQuery(queryId, TEST_SESSION, ImmutableSet.of(filterId1, filterId2), ImmutableSet.of(filterId1, filterId2), ImmutableSet.of());
    dynamicFilterService.stageCannotScheduleMoreTasks(new StageId(queryId, 1), 0, 1);
    DynamicFilter dynamicFilter = dynamicFilterService.createDynamicFilter(queryId, ImmutableList.of(new DynamicFilters.Descriptor(filterId1, df1), new DynamicFilters.Descriptor(filterId2, df2)), ImmutableMap.of(symbol1, handle1, symbol2, handle2), symbolAllocator.getTypes());
    // make sure initial dynamic filters are collected
    CompletableFuture<?> future = dynamicFilter.isBlocked();
    remoteTask.start();
    future.get();
    assertEquals(dynamicFilter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(handle1, Domain.singleValue(BIGINT, 1L))));
    assertEquals(testingTaskResource.getDynamicFiltersFetchCounter(), 1);
    // make sure dynamic filters are not collected for every status update
    assertEventually(new Duration(15, SECONDS), () -> assertGreaterThanOrEqual(testingTaskResource.getStatusFetchCounter(), 3L));
    assertEquals(testingTaskResource.getDynamicFiltersFetchCounter(), 1L, testingTaskResource.getDynamicFiltersFetchRequests().toString());
    future = dynamicFilter.isBlocked();
    testingTaskResource.setDynamicFilterDomains(new VersionedDynamicFilterDomains(2L, ImmutableMap.of(filterId2, Domain.singleValue(BIGINT, 2L))));
    future.get();
    assertEquals(dynamicFilter.getCurrentPredicate(), TupleDomain.withColumnDomains(ImmutableMap.of(handle1, Domain.singleValue(BIGINT, 1L), handle2, Domain.singleValue(BIGINT, 2L))));
    assertEquals(testingTaskResource.getDynamicFiltersFetchCounter(), 2L, testingTaskResource.getDynamicFiltersFetchRequests().toString());
    assertGreaterThanOrEqual(testingTaskResource.getStatusFetchCounter(), 4L);
    httpRemoteTaskFactory.stop();
    dynamicFilterService.stop();
}
Also used : SymbolAllocator(io.trino.sql.planner.SymbolAllocator) TestingColumnHandle(io.trino.spi.connector.TestingColumnHandle) ColumnHandle(io.trino.spi.connector.ColumnHandle) DynamicFilter(io.trino.spi.connector.DynamicFilter) Symbol(io.trino.sql.planner.Symbol) SymbolReference(io.trino.sql.tree.SymbolReference) QueryId(io.trino.spi.QueryId) StageId(io.trino.execution.StageId) RemoteTask(io.trino.execution.RemoteTask) Duration(io.airlift.units.Duration) VersionedDynamicFilterDomains(io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains) TestingColumnHandle(io.trino.spi.connector.TestingColumnHandle) AtomicLong(java.util.concurrent.atomic.AtomicLong) HttpRemoteTaskFactory(io.trino.server.HttpRemoteTaskFactory) DynamicFilterService(io.trino.server.DynamicFilterService) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) DynamicFilterId(io.trino.sql.planner.plan.DynamicFilterId) TypeOperators(io.trino.spi.type.TypeOperators) Test(org.testng.annotations.Test)

Example 4 with VersionedDynamicFilterDomains

use of io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains in project trino by trinodb.

the class TestHttpRemoteTask method createHttpRemoteTaskFactory.

private static HttpRemoteTaskFactory createHttpRemoteTaskFactory(TestingTaskResource testingTaskResource, DynamicFilterService dynamicFilterService) {
    Bootstrap app = new Bootstrap(new JsonModule(), new HandleJsonModule(), new Module() {

        @Override
        public void configure(Binder binder) {
            binder.bind(JsonMapper.class).in(SINGLETON);
            binder.bind(Metadata.class).toInstance(createTestMetadataManager());
            jsonBinder(binder).addDeserializerBinding(Type.class).to(TypeDeserializer.class);
            jsonCodecBinder(binder).bindJsonCodec(TaskStatus.class);
            jsonCodecBinder(binder).bindJsonCodec(VersionedDynamicFilterDomains.class);
            jsonBinder(binder).addSerializerBinding(Block.class).to(BlockJsonSerde.Serializer.class);
            jsonBinder(binder).addDeserializerBinding(Block.class).to(BlockJsonSerde.Deserializer.class);
            jsonCodecBinder(binder).bindJsonCodec(TaskInfo.class);
            jsonCodecBinder(binder).bindJsonCodec(TaskUpdateRequest.class);
            jsonCodecBinder(binder).bindJsonCodec(FailTaskRequest.class);
            binder.bind(TypeManager.class).toInstance(TESTING_TYPE_MANAGER);
            binder.bind(BlockEncodingManager.class).in(SINGLETON);
            binder.bind(BlockEncodingSerde.class).to(InternalBlockEncodingSerde.class).in(SINGLETON);
        }

        @Provides
        private HttpRemoteTaskFactory createHttpRemoteTaskFactory(JsonMapper jsonMapper, JsonCodec<TaskStatus> taskStatusCodec, JsonCodec<VersionedDynamicFilterDomains> dynamicFilterDomainsCodec, JsonCodec<TaskInfo> taskInfoCodec, JsonCodec<TaskUpdateRequest> taskUpdateRequestCodec, JsonCodec<FailTaskRequest> failTaskRequestCodec) {
            JaxrsTestingHttpProcessor jaxrsTestingHttpProcessor = new JaxrsTestingHttpProcessor(URI.create("http://fake.invalid/"), testingTaskResource, jsonMapper);
            TestingHttpClient testingHttpClient = new TestingHttpClient(jaxrsTestingHttpProcessor.setTrace(TRACE_HTTP));
            testingTaskResource.setHttpClient(testingHttpClient);
            return new HttpRemoteTaskFactory(new QueryManagerConfig(), TASK_MANAGER_CONFIG, testingHttpClient, new TestSqlTaskManager.MockLocationFactory(), taskStatusCodec, dynamicFilterDomainsCodec, taskInfoCodec, taskUpdateRequestCodec, failTaskRequestCodec, new RemoteTaskStats(), dynamicFilterService);
        }
    });
    Injector injector = app.doNotInitializeLogging().quiet().initialize();
    return injector.getInstance(HttpRemoteTaskFactory.class);
}
Also used : VersionedDynamicFilterDomains(io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains) TaskInfo(io.trino.execution.TaskInfo) JsonMapper(io.airlift.jaxrs.JsonMapper) JsonCodecBinder.jsonCodecBinder(io.airlift.json.JsonCodecBinder.jsonCodecBinder) Binder(com.google.inject.Binder) JsonBinder.jsonBinder(io.airlift.json.JsonBinder.jsonBinder) FailTaskRequest(io.trino.server.FailTaskRequest) JaxrsTestingHttpProcessor(io.airlift.jaxrs.testing.JaxrsTestingHttpProcessor) HandleJsonModule(io.trino.metadata.HandleJsonModule) Injector(com.google.inject.Injector) HttpRemoteTaskFactory(io.trino.server.HttpRemoteTaskFactory) TestingHttpClient(io.airlift.http.client.testing.TestingHttpClient) Bootstrap(io.airlift.bootstrap.Bootstrap) TypeDeserializer(io.trino.type.TypeDeserializer) TaskUpdateRequest(io.trino.server.TaskUpdateRequest) InternalBlockEncodingSerde(io.trino.metadata.InternalBlockEncodingSerde) BlockEncodingSerde(io.trino.spi.block.BlockEncodingSerde) TaskStatus(io.trino.execution.TaskStatus) Provides(com.google.inject.Provides) JsonModule(io.airlift.json.JsonModule) HandleJsonModule(io.trino.metadata.HandleJsonModule) TypeDeserializer(io.trino.type.TypeDeserializer) QueryManagerConfig(io.trino.execution.QueryManagerConfig) JsonModule(io.airlift.json.JsonModule) Module(com.google.inject.Module) HandleJsonModule(io.trino.metadata.HandleJsonModule)

Aggregations

VersionedDynamicFilterDomains (io.trino.execution.DynamicFiltersCollector.VersionedDynamicFilterDomains)4 TaskStatus (io.trino.execution.TaskStatus)2 FailTaskRequest (io.trino.server.FailTaskRequest)2 HttpRemoteTaskFactory (io.trino.server.HttpRemoteTaskFactory)2 TaskUpdateRequest (io.trino.server.TaskUpdateRequest)2 Domain (io.trino.spi.predicate.Domain)2 DynamicFilterId (io.trino.sql.planner.plan.DynamicFilterId)2 Test (org.testng.annotations.Test)2 Binder (com.google.inject.Binder)1 Injector (com.google.inject.Injector)1 Module (com.google.inject.Module)1 Provides (com.google.inject.Provides)1 Bootstrap (io.airlift.bootstrap.Bootstrap)1 JsonResponse (io.airlift.http.client.FullJsonResponseHandler.JsonResponse)1 HttpUriBuilder (io.airlift.http.client.HttpUriBuilder)1 Request (io.airlift.http.client.Request)1 TestingHttpClient (io.airlift.http.client.testing.TestingHttpClient)1 JsonMapper (io.airlift.jaxrs.JsonMapper)1 JaxrsTestingHttpProcessor (io.airlift.jaxrs.testing.JaxrsTestingHttpProcessor)1 JsonBinder.jsonBinder (io.airlift.json.JsonBinder.jsonBinder)1