Search in sources :

Example 16 with Elements

use of org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements in project beam by apache.

the class BeamFnDataWriteRunnerTest method createRecordingAggregator.

private BeamFnDataOutboundAggregator createRecordingAggregator(Map<String, List<WindowedValue<String>>> output, Supplier<String> bundleId) {
    PipelineOptions options = PipelineOptionsFactory.create();
    options.as(ExperimentalOptions.class).setExperiments(Arrays.asList("data_buffer_size_limit=0"));
    return new BeamFnDataOutboundAggregator(options, bundleId, new StreamObserver<Elements>() {

        @Override
        public void onNext(Elements elements) {
            for (Data data : elements.getDataList()) {
                try {
                    output.get(bundleId.get()).add(WIRE_CODER.decode(data.getData().newInput()));
                } catch (IOException e) {
                    throw new RuntimeException("Failed to decode output.");
                }
            }
        }

        @Override
        public void onError(Throwable throwable) {
        }

        @Override
        public void onCompleted() {
        }
    }, false);
}
Also used : BeamFnDataOutboundAggregator(org.apache.beam.sdk.fn.data.BeamFnDataOutboundAggregator) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) ExperimentalOptions(org.apache.beam.sdk.options.ExperimentalOptions) Data(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements.Data) IOException(java.io.IOException) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements)

Example 17 with Elements

use of org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements in project beam by apache.

the class BeamFnDataOutboundAggregatorTest method testConfiguredTimeLimit.

@Test
public void testConfiguredTimeLimit() throws Exception {
    List<Elements> values = new ArrayList<>();
    PipelineOptions options = PipelineOptionsFactory.create();
    options.as(ExperimentalOptions.class).setExperiments(Arrays.asList("data_buffer_time_limit_ms=1"));
    final CountDownLatch waitForFlush = new CountDownLatch(1);
    BeamFnDataOutboundAggregator aggregator = new BeamFnDataOutboundAggregator(options, endpoint::getInstructionId, TestStreams.withOnNext((Consumer<Elements>) e -> {
        values.add(e);
        waitForFlush.countDown();
    }).build(), false);
    // Test that it emits when time passed the time limit
    FnDataReceiver<byte[]> dataReceiver = registerOutputLocation(aggregator, endpoint, CODER);
    aggregator.start();
    dataReceiver.accept(new byte[1]);
    // wait the flush thread to flush the buffer
    waitForFlush.await();
    assertEquals(messageWithData(new byte[1]), values.get(0));
}
Also used : TestStreams(org.apache.beam.sdk.fn.test.TestStreams) Arrays(java.util.Arrays) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) ExperimentalOptions(org.apache.beam.sdk.options.ExperimentalOptions) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Coder(org.apache.beam.sdk.coders.Coder) PipelineOptionsFactory(org.apache.beam.sdk.options.PipelineOptionsFactory) ArrayList(java.util.ArrayList) Iterables(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.Iterables) ByteString(org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString) Assert.fail(org.junit.Assert.fail) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) LengthPrefixCoder(org.apache.beam.sdk.coders.LengthPrefixCoder) Parameterized(org.junit.runners.Parameterized) Matchers.empty(org.hamcrest.Matchers.empty) Collection(java.util.Collection) Matchers(org.hamcrest.Matchers) IOException(java.io.IOException) Test(org.junit.Test) BeamFnApi(org.apache.beam.model.fnexecution.v1.BeamFnApi) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Receiver(org.apache.beam.sdk.fn.data.BeamFnDataOutboundAggregator.Receiver) ByteArrayCoder(org.apache.beam.sdk.coders.ByteArrayCoder) Assert.assertEquals(org.junit.Assert.assertEquals) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) ExperimentalOptions(org.apache.beam.sdk.options.ExperimentalOptions) ArrayList(java.util.ArrayList) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 18 with Elements

use of org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements in project beam by apache.

the class ProcessBundleHandler method processBundle.

/**
 * Processes a bundle, running the start(), process(), and finish() functions. This function is
 * required to be reentrant.
 */
public BeamFnApi.InstructionResponse.Builder processBundle(BeamFnApi.InstructionRequest request) throws Exception {
    BeamFnApi.ProcessBundleResponse.Builder response = BeamFnApi.ProcessBundleResponse.newBuilder();
    BundleProcessor bundleProcessor = bundleProcessorCache.get(request, () -> {
        try {
            return createBundleProcessor(request.getProcessBundle().getProcessBundleDescriptorId(), request.getProcessBundle());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    });
    try {
        PTransformFunctionRegistry startFunctionRegistry = bundleProcessor.getStartFunctionRegistry();
        PTransformFunctionRegistry finishFunctionRegistry = bundleProcessor.getFinishFunctionRegistry();
        ExecutionStateTracker stateTracker = bundleProcessor.getStateTracker();
        try (HandleStateCallsForBundle beamFnStateClient = bundleProcessor.getBeamFnStateClient()) {
            try (Closeable closeTracker = stateTracker.activate()) {
                // Already in reverse topological order so we don't need to do anything.
                for (ThrowingRunnable startFunction : startFunctionRegistry.getFunctions()) {
                    LOG.debug("Starting function {}", startFunction);
                    startFunction.run();
                }
                if (request.getProcessBundle().hasElements()) {
                    boolean inputFinished = bundleProcessor.getInboundObserver().multiplexElements(request.getProcessBundle().getElements());
                    if (!inputFinished) {
                        throw new RuntimeException("Elements embedded in ProcessBundleRequest do not contain stream terminators for " + "all data and timer inputs. Unterminated endpoints: " + bundleProcessor.getInboundObserver().getUnfinishedEndpoints());
                    }
                } else if (!bundleProcessor.getInboundEndpointApiServiceDescriptors().isEmpty()) {
                    BeamFnDataInboundObserver2 observer = bundleProcessor.getInboundObserver();
                    beamFnDataClient.registerReceiver(request.getInstructionId(), bundleProcessor.getInboundEndpointApiServiceDescriptors(), observer);
                    observer.awaitCompletion();
                    beamFnDataClient.unregisterReceiver(request.getInstructionId(), bundleProcessor.getInboundEndpointApiServiceDescriptors());
                }
                // Need to reverse this since we want to call finish in topological order.
                for (ThrowingRunnable finishFunction : Lists.reverse(finishFunctionRegistry.getFunctions())) {
                    LOG.debug("Finishing function {}", finishFunction);
                    finishFunction.run();
                }
            }
            // If bundleProcessor has not flushed any elements, embed them in response.
            embedOutboundElementsIfApplicable(response, bundleProcessor);
            // Add all checkpointed residuals to the response.
            response.addAllResidualRoots(bundleProcessor.getSplitListener().getResidualRoots());
            // Add all metrics to the response.
            Map<String, ByteString> monitoringData = monitoringData(bundleProcessor);
            if (runnerAcceptsShortIds) {
                response.putAllMonitoringData(monitoringData);
            } else {
                for (Map.Entry<String, ByteString> metric : monitoringData.entrySet()) {
                    response.addMonitoringInfos(shortIds.get(metric.getKey()).toBuilder().setPayload(metric.getValue()));
                }
            }
            if (!bundleProcessor.getBundleFinalizationCallbackRegistrations().isEmpty()) {
                finalizeBundleHandler.registerCallbacks(bundleProcessor.getInstructionId(), ImmutableList.copyOf(bundleProcessor.getBundleFinalizationCallbackRegistrations()));
                response.setRequiresFinalization(true);
            }
        }
        // Mark the bundle processor as re-usable.
        bundleProcessorCache.release(request.getProcessBundle().getProcessBundleDescriptorId(), bundleProcessor);
        return BeamFnApi.InstructionResponse.newBuilder().setProcessBundle(response);
    } catch (Exception e) {
        // Make sure we clean-up from the active set of bundle processors.
        bundleProcessorCache.discard(bundleProcessor);
        throw e;
    }
}
Also used : PTransformFunctionRegistry(org.apache.beam.fn.harness.data.PTransformFunctionRegistry) ByteString(org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString) Closeable(java.io.Closeable) IOException(java.io.IOException) ByteString(org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString) BeamFnDataInboundObserver2(org.apache.beam.sdk.fn.data.BeamFnDataInboundObserver2) IOException(java.io.IOException) ThrowingRunnable(org.apache.beam.sdk.function.ThrowingRunnable) ExecutionStateTracker(org.apache.beam.runners.core.metrics.ExecutionStateTracker) ImmutableMap(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableMap) MetricsContainerStepMap(org.apache.beam.runners.core.metrics.MetricsContainerStepMap) Map(java.util.Map) ShortIdMap(org.apache.beam.runners.core.metrics.ShortIdMap) LinkedHashMap(java.util.LinkedHashMap) WeakHashMap(java.util.WeakHashMap) ProcessBundleResponse(org.apache.beam.model.fnexecution.v1.BeamFnApi.ProcessBundleResponse)

Example 19 with Elements

use of org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements in project beam by apache.

the class BeamFnDataOutboundAggregatorTest method testConfiguredTimeLimitExceptionPropagation.

@Test
public void testConfiguredTimeLimitExceptionPropagation() throws Exception {
    PipelineOptions options = PipelineOptionsFactory.create();
    options.as(ExperimentalOptions.class).setExperiments(Arrays.asList("data_buffer_time_limit_ms=1"));
    BeamFnDataOutboundAggregator aggregator = new BeamFnDataOutboundAggregator(options, endpoint::getInstructionId, TestStreams.withOnNext((Consumer<Elements>) e -> {
        throw new RuntimeException("");
    }).build(), false);
    // Test that it emits when time passed the time limit
    FnDataReceiver<byte[]> dataReceiver = registerOutputLocation(aggregator, endpoint, CODER);
    aggregator.start();
    dataReceiver.accept(new byte[1]);
    // wait the flush thread to flush the buffer
    while (!aggregator.flushFuture.isDone()) {
        Thread.sleep(1);
    }
    try {
        // Test that the exception caught in the flush thread is propagated to
        // the main thread when processing the next element
        dataReceiver.accept(new byte[1]);
        fail();
    } catch (Exception e) {
    // expected
    }
    aggregator = new BeamFnDataOutboundAggregator(options, endpoint::getInstructionId, TestStreams.withOnNext((Consumer<Elements>) e -> {
        throw new RuntimeException("");
    }).build(), false);
    dataReceiver = registerOutputLocation(aggregator, endpoint, CODER);
    aggregator.start();
    dataReceiver.accept(new byte[1]);
    // wait the flush thread to flush the buffer
    while (!aggregator.flushFuture.isDone()) {
        Thread.sleep(1);
    }
    try {
        // Test that the exception caught in the flush thread is propagated to
        // the main thread when closing
        aggregator.sendOrCollectBufferedDataAndFinishOutboundStreams();
        fail();
    } catch (Exception e) {
    // expected
    }
}
Also used : TestStreams(org.apache.beam.sdk.fn.test.TestStreams) Arrays(java.util.Arrays) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) ExperimentalOptions(org.apache.beam.sdk.options.ExperimentalOptions) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Coder(org.apache.beam.sdk.coders.Coder) PipelineOptionsFactory(org.apache.beam.sdk.options.PipelineOptionsFactory) ArrayList(java.util.ArrayList) Iterables(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.Iterables) ByteString(org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString) Assert.fail(org.junit.Assert.fail) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) LengthPrefixCoder(org.apache.beam.sdk.coders.LengthPrefixCoder) Parameterized(org.junit.runners.Parameterized) Matchers.empty(org.hamcrest.Matchers.empty) Collection(java.util.Collection) Matchers(org.hamcrest.Matchers) IOException(java.io.IOException) Test(org.junit.Test) BeamFnApi(org.apache.beam.model.fnexecution.v1.BeamFnApi) Consumer(java.util.function.Consumer) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Receiver(org.apache.beam.sdk.fn.data.BeamFnDataOutboundAggregator.Receiver) ByteArrayCoder(org.apache.beam.sdk.coders.ByteArrayCoder) Assert.assertEquals(org.junit.Assert.assertEquals) Consumer(java.util.function.Consumer) PipelineOptions(org.apache.beam.sdk.options.PipelineOptions) ExperimentalOptions(org.apache.beam.sdk.options.ExperimentalOptions) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) IOException(java.io.IOException) Test(org.junit.Test)

Example 20 with Elements

use of org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements in project beam by apache.

the class BeamFnDataOutboundAggregatorTest method testWithDefaultBuffer.

@Test
public void testWithDefaultBuffer() throws Exception {
    final List<Elements> values = new ArrayList<>();
    final AtomicBoolean onCompletedWasCalled = new AtomicBoolean();
    BeamFnDataOutboundAggregator aggregator = new BeamFnDataOutboundAggregator(PipelineOptionsFactory.create(), endpoint::getInstructionId, TestStreams.<Elements>withOnNext(values::add).withOnCompleted(() -> onCompletedWasCalled.set(true)).build(), false);
    // Test that nothing is emitted till the default buffer size is surpassed.
    FnDataReceiver<byte[]> dataReceiver = registerOutputLocation(aggregator, endpoint, CODER);
    aggregator.start();
    dataReceiver.accept(new byte[BeamFnDataOutboundAggregator.DEFAULT_BUFFER_LIMIT_BYTES - 50]);
    assertThat(values, empty());
    // Test that when we cross the buffer, we emit.
    dataReceiver.accept(new byte[50]);
    assertEquals(messageWithData(new byte[BeamFnDataOutboundAggregator.DEFAULT_BUFFER_LIMIT_BYTES - 50], new byte[50]), values.get(0));
    // Test that nothing is emitted till the default buffer size is surpassed after a reset
    dataReceiver.accept(new byte[BeamFnDataOutboundAggregator.DEFAULT_BUFFER_LIMIT_BYTES - 50]);
    assertEquals(1, values.size());
    // Test that when we cross the buffer, we emit.
    dataReceiver.accept(new byte[50]);
    assertEquals(messageWithData(new byte[BeamFnDataOutboundAggregator.DEFAULT_BUFFER_LIMIT_BYTES - 50], new byte[50]), values.get(1));
    // Test that when we close with an empty buffer we only have one end of stream
    aggregator.sendOrCollectBufferedDataAndFinishOutboundStreams();
    assertEquals(endMessage(), values.get(2));
    // Test that we can close twice.
    aggregator.sendOrCollectBufferedDataAndFinishOutboundStreams();
    assertEquals(endMessage(), values.get(2));
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayList(java.util.ArrayList) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) Test(org.junit.Test)

Aggregations

Elements (org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements)20 ArrayList (java.util.ArrayList)17 Test (org.junit.Test)17 ByteString (org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString)13 CountDownLatch (java.util.concurrent.CountDownLatch)8 ExecutorService (java.util.concurrent.ExecutorService)7 Collection (java.util.Collection)6 BeamFnApi (org.apache.beam.model.fnexecution.v1.BeamFnApi)6 WindowedValue (org.apache.beam.sdk.util.WindowedValue)6 ManagedChannel (org.apache.beam.vendor.grpc.v1p43p2.io.grpc.ManagedChannel)6 IOException (java.io.IOException)5 LinkedBlockingQueue (java.util.concurrent.LinkedBlockingQueue)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 ApiServiceDescriptor (org.apache.beam.model.pipeline.v1.Endpoints.ApiServiceDescriptor)5 LogicalEndpoint (org.apache.beam.sdk.fn.data.LogicalEndpoint)5 ExperimentalOptions (org.apache.beam.sdk.options.ExperimentalOptions)5 PipelineOptions (org.apache.beam.sdk.options.PipelineOptions)5 StreamObserver (org.apache.beam.vendor.grpc.v1p43p2.io.grpc.stub.StreamObserver)5 Coder (org.apache.beam.sdk.coders.Coder)4 RunWith (org.junit.runner.RunWith)4