Search in sources :

Example 11 with Input

use of org.talend.sdk.component.runtime.input.Input in project component-runtime by Talend.

the class BaseComponentsHandler method collect.

/**
 * Collects data emitted from this mapper. If the split creates more than one
 * mapper, it will create as much threads as mappers otherwise it will use the
 * caller thread.
 *
 * IMPORTANT: don't forget to consume all the stream to ensure the underlying
 * { @see org.talend.sdk.component.runtime.input.Input} is closed.
 *
 * @param recordType the record type to use to type the returned type.
 * @param mapper the mapper to go through.
 * @param maxRecords maximum number of records, allows to stop the source when
 * infinite.
 * @param concurrency requested (1 can be used instead if <= 0) concurrency for the reader execution.
 * @param <T> the returned type of the records of the mapper.
 * @return all the records emitted by the mapper.
 */
@Override
public <T> Stream<T> collect(final Class<T> recordType, final Mapper mapper, final int maxRecords, final int concurrency) {
    mapper.start();
    final State state = STATE.get();
    final long assess = mapper.assess();
    final int proc = Math.max(1, concurrency);
    final List<Mapper> mappers = mapper.split(Math.max(assess / proc, 1));
    switch(mappers.size()) {
        case 0:
            return Stream.empty();
        case 1:
            return StreamDecorator.decorate(asStream(asIterator(mappers.iterator().next().create(), new AtomicInteger(maxRecords))), collect -> {
                try {
                    collect.run();
                } finally {
                    mapper.stop();
                }
            });
        default:
            // N producers-1 consumer pattern
            final AtomicInteger threadCounter = new AtomicInteger(0);
            final ExecutorService es = Executors.newFixedThreadPool(mappers.size(), r -> new Thread(r) {

                {
                    setName(BaseComponentsHandler.this.getClass().getSimpleName() + "-pool-" + abs(mapper.hashCode()) + "-" + threadCounter.incrementAndGet());
                }
            });
            final AtomicInteger recordCounter = new AtomicInteger(maxRecords);
            final Semaphore permissions = new Semaphore(0);
            final Queue<T> records = new ConcurrentLinkedQueue<>();
            final CountDownLatch latch = new CountDownLatch(mappers.size());
            final List<? extends Future<?>> tasks = mappers.stream().map(Mapper::create).map(input -> (Iterator<T>) asIterator(input, recordCounter)).map(it -> es.submit(() -> {
                try {
                    while (it.hasNext()) {
                        final T next = it.next();
                        records.add(next);
                        permissions.release();
                    }
                } finally {
                    latch.countDown();
                }
            })).collect(toList());
            es.shutdown();
            final int timeout = Integer.getInteger("talend.component.junit.timeout", 5);
            new Thread() {

                {
                    setName(BaseComponentsHandler.class.getSimpleName() + "-monitor_" + abs(mapper.hashCode()));
                }

                @Override
                public void run() {
                    try {
                        latch.await(timeout, MINUTES);
                    } catch (final InterruptedException e) {
                        Thread.interrupted();
                    } finally {
                        permissions.release();
                    }
                }
            }.start();
            return StreamDecorator.decorate(asStream(new Iterator<T>() {

                @Override
                public boolean hasNext() {
                    try {
                        permissions.acquire();
                    } catch (final InterruptedException e) {
                        Thread.interrupted();
                        fail(e.getMessage());
                    }
                    return !records.isEmpty();
                }

                @Override
                public T next() {
                    T poll = records.poll();
                    if (poll != null) {
                        return mapRecord(state, recordType, poll);
                    }
                    return null;
                }
            }), task -> {
                try {
                    task.run();
                } finally {
                    tasks.forEach(f -> {
                        try {
                            f.get(5, SECONDS);
                        } catch (final InterruptedException e) {
                            Thread.interrupted();
                        } catch (final ExecutionException | TimeoutException e) {
                        // no-op
                        } finally {
                            if (!f.isDone() && !f.isCancelled()) {
                                f.cancel(true);
                            }
                        }
                    });
                }
            });
    }
}
Also used : SimpleFactory.configurationByExample(org.talend.sdk.component.junit.SimpleFactory.configurationByExample) Spliterators(java.util.Spliterators) ComponentFamilyMeta(org.talend.sdk.component.runtime.manager.ComponentFamilyMeta) RequiredArgsConstructor(lombok.RequiredArgsConstructor) TimeoutException(java.util.concurrent.TimeoutException) MINUTES(java.util.concurrent.TimeUnit.MINUTES) HashMap(java.util.HashMap) Math.abs(java.lang.Math.abs) JsonbConfig(javax.json.bind.JsonbConfig) ArrayList(java.util.ArrayList) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) PreComputedJsonpProvider(org.talend.sdk.component.runtime.manager.json.PreComputedJsonpProvider) Assert.fail(org.junit.Assert.fail) StreamSupport(java.util.stream.StreamSupport) Input(org.talend.sdk.component.runtime.input.Input) ExecutorService(java.util.concurrent.ExecutorService) Collections.emptyMap(java.util.Collections.emptyMap) JsonObject(javax.json.JsonObject) Iterator(java.util.Iterator) ContainerComponentRegistry(org.talend.sdk.component.runtime.manager.ContainerComponentRegistry) Semaphore(java.util.concurrent.Semaphore) Collection(java.util.Collection) Set(java.util.Set) Filter(org.apache.xbean.finder.filter.Filter) Processor(org.talend.sdk.component.runtime.output.Processor) Collectors.joining(java.util.stream.Collectors.joining) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) CountDownLatch(java.util.concurrent.CountDownLatch) Lifecycle(org.talend.sdk.component.runtime.base.Lifecycle) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) Mapper(org.talend.sdk.component.runtime.input.Mapper) Slf4j(lombok.extern.slf4j.Slf4j) Stream(java.util.stream.Stream) StreamDecorator(org.talend.sdk.component.junit.lang.StreamDecorator) Job(org.talend.sdk.component.runtime.manager.chain.Job) JarLocation.jarLocation(org.apache.ziplock.JarLocation.jarLocation) Optional(java.util.Optional) Jsonb(javax.json.bind.Jsonb) Queue(java.util.Queue) ComponentManager(org.talend.sdk.component.runtime.manager.ComponentManager) Spliterator(java.util.Spliterator) SECONDS(java.util.concurrent.TimeUnit.SECONDS) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Semaphore(java.util.concurrent.Semaphore) CountDownLatch(java.util.concurrent.CountDownLatch) Mapper(org.talend.sdk.component.runtime.input.Mapper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) Iterator(java.util.Iterator) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

Input (org.talend.sdk.component.runtime.input.Input)11 Mapper (org.talend.sdk.component.runtime.input.Mapper)9 JsonObject (javax.json.JsonObject)4 Map (java.util.Map)3 Jsonb (javax.json.bind.Jsonb)3 Test (org.junit.Test)3 PartitionMapper (org.talend.sdk.component.api.input.PartitionMapper)3 ChainedMapper (org.talend.sdk.component.runtime.manager.chain.ChainedMapper)3 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 Optional (java.util.Optional)2 ExecutorService (java.util.concurrent.ExecutorService)2 SECONDS (java.util.concurrent.TimeUnit.SECONDS)2 Collectors.toMap (java.util.stream.Collectors.toMap)2 Slf4j (lombok.extern.slf4j.Slf4j)2 PBegin (org.apache.beam.sdk.values.PBegin)2 Source (org.talend.sdk.component.junit.component.Source)2 Sample (org.talend.sdk.component.runtime.beam.data.Sample)2 BeamMapperImpl (org.talend.sdk.component.runtime.beam.impl.BeamMapperImpl)2 JobStateAware (org.talend.sdk.component.runtime.di.JobStateAware)2