Search in sources :

Example 1 with Elements

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

the class ServerFactoryTest method runTestUsing.

private Endpoints.ApiServiceDescriptor runTestUsing(ServerFactory serverFactory, ManagedChannelFactory channelFactory) throws Exception {
    Endpoints.ApiServiceDescriptor.Builder apiServiceDescriptorBuilder = Endpoints.ApiServiceDescriptor.newBuilder();
    final Collection<Elements> serverElements = new ArrayList<>();
    final CountDownLatch clientHangedUp = new CountDownLatch(1);
    CallStreamObserver<Elements> serverInboundObserver = TestStreams.withOnNext(serverElements::add).withOnCompleted(clientHangedUp::countDown).build();
    TestDataService service = new TestDataService(serverInboundObserver);
    Server server = serverFactory.allocateAddressAndCreate(ImmutableList.of(service), apiServiceDescriptorBuilder);
    assertFalse(server.isShutdown());
    ManagedChannel channel = channelFactory.forDescriptor(apiServiceDescriptorBuilder.build());
    BeamFnDataGrpc.BeamFnDataStub stub = BeamFnDataGrpc.newStub(channel);
    final Collection<BeamFnApi.Elements> clientElements = new ArrayList<>();
    final CountDownLatch serverHangedUp = new CountDownLatch(1);
    CallStreamObserver<BeamFnApi.Elements> clientInboundObserver = TestStreams.withOnNext(clientElements::add).withOnCompleted(serverHangedUp::countDown).build();
    StreamObserver<Elements> clientOutboundObserver = stub.data(clientInboundObserver);
    StreamObserver<BeamFnApi.Elements> serverOutboundObserver = service.outboundObservers.take();
    clientOutboundObserver.onNext(CLIENT_DATA);
    serverOutboundObserver.onNext(SERVER_DATA);
    clientOutboundObserver.onCompleted();
    clientHangedUp.await();
    serverOutboundObserver.onCompleted();
    serverHangedUp.await();
    assertThat(clientElements, contains(SERVER_DATA));
    assertThat(serverElements, contains(CLIENT_DATA));
    return apiServiceDescriptorBuilder.build();
}
Also used : ApiServiceDescriptor(org.apache.beam.model.pipeline.v1.Endpoints.ApiServiceDescriptor) Server(org.apache.beam.vendor.grpc.v1p43p2.io.grpc.Server) ArrayList(java.util.ArrayList) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) CountDownLatch(java.util.concurrent.CountDownLatch) ManagedChannel(org.apache.beam.vendor.grpc.v1p43p2.io.grpc.ManagedChannel) BeamFnDataGrpc(org.apache.beam.model.fnexecution.v1.BeamFnDataGrpc)

Example 2 with Elements

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

the class ServerFactoryTest method usesUrlFactory.

@Test
public void usesUrlFactory() throws Exception {
    ServerFactory serverFactory = ServerFactory.createWithUrlFactory((host, port) -> "foo");
    CallStreamObserver<Elements> observer = TestStreams.withOnNext((Elements unused) -> {
    }).withOnCompleted(() -> {
    }).build();
    TestDataService service = new TestDataService(observer);
    ApiServiceDescriptor.Builder descriptorBuilder = ApiServiceDescriptor.newBuilder();
    grpcCleanupRule.register(serverFactory.allocateAddressAndCreate(ImmutableList.of(service), descriptorBuilder));
    assertThat(descriptorBuilder.getUrl(), is("foo"));
}
Also used : ApiServiceDescriptor(org.apache.beam.model.pipeline.v1.Endpoints.ApiServiceDescriptor) ServerFactory(org.apache.beam.sdk.fn.server.ServerFactory) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) Test(org.junit.Test)

Example 3 with Elements

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

the class ProcessBundleHandler method embedOutboundElementsIfApplicable.

private void embedOutboundElementsIfApplicable(ProcessBundleResponse.Builder response, BundleProcessor bundleProcessor) {
    if (bundleProcessor.getOutboundAggregators().isEmpty()) {
        return;
    }
    List<Elements> collectedElements = new ArrayList<>(bundleProcessor.getOutboundAggregators().size());
    boolean hasFlushedAggregator = false;
    for (BeamFnDataOutboundAggregator aggregator : bundleProcessor.getOutboundAggregators().values()) {
        Elements elements = aggregator.sendOrCollectBufferedDataAndFinishOutboundStreams();
        if (elements == null) {
            hasFlushedAggregator = true;
        }
        collectedElements.add(elements);
    }
    if (!hasFlushedAggregator) {
        Elements.Builder elementsToEmbed = Elements.newBuilder();
        for (Elements collectedElement : collectedElements) {
            elementsToEmbed.mergeFrom(collectedElement);
        }
        response.setElements(elementsToEmbed.build());
    } else {
        // Since there was at least one flushed aggregator, we have to use the aggregators that were
        // able to successfully collect their elements to emit them and can not send them as part of
        // the ProcessBundleResponse.
        int i = 0;
        for (BeamFnDataOutboundAggregator aggregator : bundleProcessor.getOutboundAggregators().values()) {
            Elements elements = collectedElements.get(i++);
            if (elements != null) {
                aggregator.sendElements(elements);
            }
        }
    }
}
Also used : BeamFnDataOutboundAggregator(org.apache.beam.sdk.fn.data.BeamFnDataOutboundAggregator) ArrayList(java.util.ArrayList) Elements(org.apache.beam.model.fnexecution.v1.BeamFnApi.Elements) TimerEndpoint(org.apache.beam.sdk.fn.data.TimerEndpoint) DataEndpoint(org.apache.beam.sdk.fn.data.DataEndpoint)

Example 4 with Elements

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

the class BeamFnDataGrpcMultiplexerTest method testInboundObserverBlocksTillConsumerConnects.

@Test
public void testInboundObserverBlocksTillConsumerConnects() throws Exception {
    final Collection<BeamFnApi.Elements> outboundValues = new ArrayList<>();
    final Collection<KV<ByteString, Boolean>> dataInboundValues = new ArrayList<>();
    final Collection<KV<ByteString, Boolean>> timerInboundValues = new ArrayList<>();
    final BeamFnDataGrpcMultiplexer multiplexer = new BeamFnDataGrpcMultiplexer(DESCRIPTOR, OutboundObserverFactory.clientDirect(), inboundObserver -> TestStreams.withOnNext(outboundValues::add).build());
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.submit(() -> {
        // Purposefully sleep to simulate a delay in a consumer connecting.
        Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
        multiplexer.registerConsumer(DATA_LOCATION, (payload, isLast) -> dataInboundValues.add(KV.of(payload, isLast)));
        multiplexer.registerConsumer(TIMER_LOCATION, (payload, isLast) -> timerInboundValues.add(KV.of(payload, isLast)));
    }).get();
    multiplexer.getInboundObserver().onNext(ELEMENTS);
    assertTrue(multiplexer.hasConsumer(DATA_LOCATION));
    assertTrue(multiplexer.hasConsumer(TIMER_LOCATION));
    // Ensure that when we see a terminal Elements object, we remove the consumer
    multiplexer.getInboundObserver().onNext(TERMINAL_ELEMENTS);
    assertFalse(multiplexer.hasConsumer(DATA_LOCATION));
    assertFalse(multiplexer.hasConsumer(TIMER_LOCATION));
    // Assert that normal and terminal Elements are passed to the consumer
    assertThat(dataInboundValues, contains(KV.of(ELEMENTS.getData(0).getData(), false), KV.of(ByteString.EMPTY, true)));
    assertThat(timerInboundValues, contains(KV.of(ELEMENTS.getTimers(0).getTimers(), false), KV.of(ByteString.EMPTY, true)));
}
Also used : Endpoints(org.apache.beam.model.pipeline.v1.Endpoints) TestStreams(org.apache.beam.sdk.fn.test.TestStreams) KV(org.apache.beam.sdk.values.KV) Collection(java.util.Collection) OutboundObserverFactory(org.apache.beam.sdk.fn.stream.OutboundObserverFactory) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) BeamFnApi(org.apache.beam.model.fnexecution.v1.BeamFnApi) Executors(java.util.concurrent.Executors) ArrayList(java.util.ArrayList) TimeUnit(java.util.concurrent.TimeUnit) Matchers.contains(org.hamcrest.Matchers.contains) Assert.assertFalse(org.junit.Assert.assertFalse) ByteString(org.apache.beam.vendor.grpc.v1p43p2.com.google.protobuf.ByteString) Uninterruptibles(org.apache.beam.vendor.guava.v26_0_jre.com.google.common.util.concurrent.Uninterruptibles) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ExecutorService(java.util.concurrent.ExecutorService) ArrayList(java.util.ArrayList) ExecutorService(java.util.concurrent.ExecutorService) KV(org.apache.beam.sdk.values.KV) Test(org.junit.Test)

Example 5 with Elements

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

the class BeamFnDataReadRunner method trySplit.

public void trySplit(ProcessBundleSplitRequest request, ProcessBundleSplitResponse.Builder response) {
    DesiredSplit desiredSplit = request.getDesiredSplitsMap().get(pTransformId);
    if (desiredSplit == null) {
        return;
    }
    long totalBufferSize = desiredSplit.getEstimatedInputElements();
    List<Long> allowedSplitPoints = new ArrayList<>(desiredSplit.getAllowedSplitPointsList());
    HandlesSplits splittingConsumer = null;
    if (consumer instanceof HandlesSplits) {
        splittingConsumer = ((HandlesSplits) consumer);
    }
    synchronized (splittingLock) {
        // provide.
        if (index == stopIndex) {
            return;
        }
        // being released.
        if (!request.getInstructionId().equals(processBundleInstructionIdSupplier.get())) {
            return;
        }
        // split request is bounded incorrectly, use the stop index as the upper bound.
        if (totalBufferSize < index + 1) {
            totalBufferSize = index + 1;
        } else if (totalBufferSize > stopIndex) {
            totalBufferSize = stopIndex;
        }
        // In the case where we have yet to process an element, set the current element progress to 1.
        double currentElementProgress = 1;
        // progress defaulting to 0.5 if no progress was able to get fetched.
        if (index >= 0) {
            if (splittingConsumer != null) {
                currentElementProgress = splittingConsumer.getProgress();
            } else {
                currentElementProgress = 0.5;
            }
        }
        // Now figure out where to split.
        // 
        // The units here (except for keepOfElementRemainder) are all in terms of number or
        // (possibly fractional) elements.
        // Compute the amount of "remaining" work that we know of.
        double remainder = totalBufferSize - index - currentElementProgress;
        // Compute the number of elements (including fractional elements) that we should "keep".
        double keep = remainder * desiredSplit.getFractionOfRemainder();
        // splittable.
        if (currentElementProgress < 1) {
            // See if the amount we need to keep falls within the current element's remainder and if
            // so, attempt to split it.
            double keepOfElementRemainder = keep / (1 - currentElementProgress);
            // If both index and index are allowed split point, we can split at index.
            if (keepOfElementRemainder < 1 && isValidSplitPoint(allowedSplitPoints, index) && isValidSplitPoint(allowedSplitPoints, index + 1)) {
                SplitResult splitResult = splittingConsumer != null ? splittingConsumer.trySplit(keepOfElementRemainder) : null;
                if (splitResult != null) {
                    stopIndex = index + 1;
                    response.addAllPrimaryRoots(splitResult.getPrimaryRoots()).addAllResidualRoots(splitResult.getResidualRoots()).addChannelSplitsBuilder().setLastPrimaryElement(index - 1).setFirstResidualElement(stopIndex);
                    return;
                }
            }
        }
        // Otherwise, split at the closest allowed element boundary.
        long newStopIndex = index + Math.max(1, Math.round(currentElementProgress + keep));
        if (!isValidSplitPoint(allowedSplitPoints, newStopIndex)) {
            // Choose the closest allowed split point.
            Collections.sort(allowedSplitPoints);
            int closestSplitPointIndex = -(Collections.binarySearch(allowedSplitPoints, newStopIndex) + 1);
            if (closestSplitPointIndex == 0) {
                newStopIndex = allowedSplitPoints.get(0);
            } else if (closestSplitPointIndex == allowedSplitPoints.size()) {
                newStopIndex = allowedSplitPoints.get(closestSplitPointIndex - 1);
            } else {
                long prevPoint = allowedSplitPoints.get(closestSplitPointIndex - 1);
                long nextPoint = allowedSplitPoints.get(closestSplitPointIndex);
                if (index < prevPoint && newStopIndex - prevPoint < nextPoint - newStopIndex) {
                    newStopIndex = prevPoint;
                } else {
                    newStopIndex = nextPoint;
                }
            }
        }
        if (newStopIndex < stopIndex && newStopIndex > index) {
            stopIndex = newStopIndex;
            response.addChannelSplitsBuilder().setLastPrimaryElement(stopIndex - 1).setFirstResidualElement(stopIndex);
            return;
        }
    }
}
Also used : SplitResult(org.apache.beam.fn.harness.HandlesSplits.SplitResult) ArrayList(java.util.ArrayList) DesiredSplit(org.apache.beam.model.fnexecution.v1.BeamFnApi.ProcessBundleSplitRequest.DesiredSplit)

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