A preview call can be quite expensive and cause timeout in a cluster. As a short term fix we identified 2 (hopefully) small fixes:

- make the call cancellable, the main issue here seems to be that preview calls search without using a parent task id(see this fix for data feeds: https://github.com/elastic/elasticsearch/pull/88142/files#diff-aba58244cb8f9dfa3ac3b6efeb02259e3d5956576f56c1ff5e243dd2aac27381)
- pass the timeout parameter of the preview call to the search call, currently a timeout can be specified, but is ignored for the inner search call, which is executed with no timeout (see https://www.elastic.co/guide/en/elasticsearch/reference/master/search-search.html#search-search-api-query-params).

Both changes are bugs and shall be relatively simple to implement and considered for backport to the 7.17 branch.

@przemekwitek can you have a look at this?

related: #88010
x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/transforms/pivot/PivotTests.java
}
    private static void assertInvalidTransform(Client client, SourceConfig source, Function pivot) throws Exception {
        validate(client, source, pivot, false);
    }
    private static void validate(Client client, SourceConfig source, Function pivot, boolean expectValid) throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<Exception> exceptionHolder = new AtomicReference<>();
        pivot.validateQuery(client, source, ActionListener.wrap(validity -> {
            assertEquals(expectValid, validity);
            latch.countDown();
        }, e -> {
            exceptionHolder.set(e);
            latch.countDown();
        }));
        assertTrue(latch.await(100, TimeUnit.MILLISECONDS));
        if (expectValid && exceptionHolder.get() != null) {
            throw exceptionHolder.get();
        } else if (expectValid == false && exceptionHolder.get() == null) {
            fail("Expected config to be invalid");
        }
    }
    
    private static class TestSpatialPlugin extends SpatialPlugin {
        @Override
        protected XPackLicenseState getLicenseState() {
            return new XPackLicenseState(System::currentTimeMillis);
        }
    }
}