All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nohope.test.stress.StressTest Maven / Gradle / Ivy

The newest version!
package org.nohope.test.stress;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.nohope.test.stress.actions.Scenario;
import org.nohope.test.stress.functors.Call;
import org.nohope.test.stress.functors.Get;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.function.Function;

/**
 * @author ketoth xupack
 * @since 2013-12-26 21:39
 */
public final class StressTest {
    private final Builder builder;

    private StressTest(final Builder builder) {
        this.builder = builder;
    }

    public static StressTest instance() {
        return new Builder().build();
    }

    /**
     * This method runs {@code threadsNumber}, each performing {@code cycleCount}
     * invocations of {@code scenario}
     */
    public PreparedStressTest prepare(final int threadsNumber, final int cycleCount,
                                      final Scenario scenario) {
        final Map accumulators = new ConcurrentHashMap<>(16, 0.75f, threadsNumber);
        final Function accumulatorLoader = ActionStatsAccumulator::new;
        final Function accumulatorGetter =
                name -> accumulators.computeIfAbsent(name, accumulatorLoader);

        final List providers = new ArrayList<>(threadsNumber * cycleCount);
        for (int i = 0; i < threadsNumber; i++) {
            for (int j = i * cycleCount; j < (i + 1) * cycleCount; j++) {
                providers.add(new MeasureProvider(i, j, accumulatorGetter));
            }
        }

        final List threads = new ArrayList<>();
        for (int i = 0; i < threadsNumber; i++) {
            final int k = i;
            threads.add(new Thread(() -> {
                for (int j = k * cycleCount; j < (k + 1) * cycleCount; j++) {
                    try {
                        scenario.doAction(providers.get(j));
                    } catch (final Exception e) {
                        // TODO: print skipped
                    }
                }
            }, "stress-worker-" + k));
        }

        return new PreparedStressTest(threadsNumber, cycleCount,
                Collections.emptyList(), accumulators.values(), threads,
                builder.metricsInterval);
    }

    /**
     * This method runs {@code coordinatorThreadsCount} threads, performing
     * {@code cyclesPerCoordinatorCount} invocations of {@code scenario}
     * 

* * Coordinator invokes each kind {@link MeasureProvider#get(String, Get)} or * {@link MeasureProvider#call(String, Call)} in separate thread pools sized to * {@code actionThreadPoolSize}. */ public PreparedStressTest prepare(final int coordinatorThreadsCount, final int cyclesPerCoordinatorCount, final int actionThreadPoolSize, final Scenario scenario) { final Map executors = new ConcurrentHashMap<>(16, 0.75f, coordinatorThreadsCount); final Function executorLoader = name -> { final String nameFormat = "prepare-pool-" + name + "-%d"; final ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(nameFormat).build(); return Executors.newFixedThreadPool(actionThreadPoolSize, threadFactory); }; final Function executorGetter = name -> executors.computeIfAbsent(name, executorLoader); final Map accumulators = new ConcurrentHashMap<>(16, 0.75f, actionThreadPoolSize * coordinatorThreadsCount); final Function accumulatorLoader = ActionStatsAccumulator::new; final Function accumulatorGetter = name -> accumulators.computeIfAbsent(name, accumulatorLoader); final int cycleCount = coordinatorThreadsCount * cyclesPerCoordinatorCount; final List providers = new ArrayList<>(cycleCount); for (int i = 0; i < actionThreadPoolSize; i++) { for (int j = i * cyclesPerCoordinatorCount; j < (i + 1) * cyclesPerCoordinatorCount; j++) { providers.add(new PooledMeasureProvider(i, j, executorGetter, accumulatorGetter)); } } final List threads = new ArrayList<>(); for (int i = 0; i < coordinatorThreadsCount; i++) { final int k = i; threads.add(new Thread(() -> { for (int j = k * cyclesPerCoordinatorCount; j < (k + 1) * cyclesPerCoordinatorCount; j++) { try { scenario.doAction(providers.get(j)); } catch (final Exception e) { // TODO: print skipped } } }, "stress-worker-" + k)); } return new PreparedStressTest(actionThreadPoolSize, cycleCount, executors.values(), accumulators.values(), threads, builder.metricsInterval); } public static class Builder { private Duration metricsInterval = Duration.ofSeconds(2); public Builder metricsInterval(Duration metricsInterval) { this.metricsInterval = metricsInterval; return this; } public StressTest build() { return new StressTest(this); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy