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);
}
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)));
}
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();
}
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);
}
Aggregations