Search in sources :

Example 1 with CycleResultSegmentBuffer

use of io.engineblock.activityapi.cyclelog.buffers.results.CycleResultSegmentBuffer in project engineblock by engineblock.

the class CoreMotor method run.

@Override
public void run() {
    try {
        Timer cyclesTimer = ActivityMetrics.timer(activity.getActivityDef(), "cycles");
        Timer phasesTimer = ActivityMetrics.timer(activity.getActivityDef(), "phases");
        Timer stridesTimer = ActivityMetrics.timer(activity.getActivityDef(), "strides");
        Timer inputTimer = ActivityMetrics.timer(activity.getActivityDef(), "read-input");
        strideRateLimiter = activity.getStrideLimiter();
        cycleRateLimiter = activity.getCycleLimiter();
        phaseRateLimiter = activity.getPhaseLimiter();
        if (slotState.get() == Finished) {
            logger.warn("Input was already exhausted for slot " + slotId + ", remaining in finished state.");
        }
        slotStateTracker.enterState(Running);
        MultiPhaseAction multiPhaseAction = null;
        if (action instanceof MultiPhaseAction) {
            multiPhaseAction = ((MultiPhaseAction) action);
        }
        long cyclenum;
        action.init();
        if (input instanceof Startable) {
            ((Startable) input).start();
        }
        if (strideRateLimiter != null) {
            // block for strides rate limiter
            strideRateLimiter.start();
        }
        long strideDelay = 0L;
        long cycleDelay = 0L;
        long phaseDelay = 0L;
        while (slotState.get() == Running) {
            CycleSegment cycleSegment = null;
            try (Timer.Context inputTime = inputTimer.time()) {
                cycleSegment = input.getInputSegment(stride);
            }
            if (cycleSegment == null) {
                logger.debug("input exhausted (input " + input + ") via null segment, stopping motor thread " + slotId);
                slotStateTracker.enterState(Finished);
                continue;
            }
            CycleResultSegmentBuffer segBuffer = new CycleResultSegmentBuffer(stride);
            if (strideRateLimiter != null) {
                // block for strides rate limiter
                strideDelay = strideRateLimiter.acquire();
            }
            // try (Timer.Context stridesTime = stridesTimer.time()) {
            long strideStart = System.nanoTime();
            try {
                while (!cycleSegment.isExhausted()) {
                    cyclenum = cycleSegment.nextCycle();
                    if (cyclenum < 0) {
                        if (cycleSegment.isExhausted()) {
                            logger.trace("input exhausted (input " + input + ") via negative read, stopping motor thread " + slotId);
                            slotStateTracker.enterState(Finished);
                            continue;
                        }
                    }
                    if (slotState.get() != Running) {
                        logger.trace("motor stopped after input (input " + cyclenum + "), stopping motor thread " + slotId);
                        continue;
                    }
                    int result = -1;
                    if (cycleRateLimiter != null) {
                        // Block for cycle rate limiter
                        cycleDelay = cycleRateLimiter.acquire();
                    }
                    // Phases are rate limited independently from overall cycles, but each cycle has at least one phase.
                    if (phaseRateLimiter != null) {
                        // Block for cycle rate limiter
                        phaseDelay = phaseRateLimiter.acquire();
                    }
                    // try (Timer.Context cycleTime = cyclesTimer.time()) {
                    long cycleStart = System.nanoTime();
                    try {
                        logger.trace("cycle " + cyclenum);
                        try (Timer.Context phaseTime = phasesTimer.time()) {
                            result = action.runCycle(cyclenum);
                        }
                        if (multiPhaseAction != null) {
                            while (multiPhaseAction.incomplete()) {
                                if (phaseRateLimiter != null) {
                                    // Block for cycle rate limiter
                                    phaseDelay = phaseRateLimiter.acquire();
                                }
                                try (Timer.Context phaseTime = phasesTimer.time()) {
                                    result = multiPhaseAction.runPhase(cyclenum);
                                }
                            }
                        }
                    } finally {
                        long cycleEnd = System.nanoTime();
                        cyclesTimer.update((cycleEnd - cycleStart) + cycleDelay, TimeUnit.NANOSECONDS);
                    }
                    segBuffer.append(cyclenum, result);
                }
            } finally {
                long strideEnd = System.nanoTime();
                stridesTimer.update((strideEnd - strideStart) + strideDelay, TimeUnit.NANOSECONDS);
            }
            if (output != null) {
                CycleResultsSegment outputBuffer = segBuffer.toReader();
                try {
                    output.onCycleResultSegment(outputBuffer);
                } catch (Exception t) {
                    logger.error("Error while feeding result segment " + outputBuffer + " to output '" + output + "', error:" + t);
                    throw t;
                }
            }
        }
        if (slotState.get() == Stopping) {
            slotStateTracker.enterState(Stopped);
        }
    } catch (Throwable t) {
        logger.error("Error in core motor loop:" + t, t);
        throw t;
    }
}
Also used : Timer(com.codahale.metrics.Timer) CycleResultSegmentBuffer(io.engineblock.activityapi.cyclelog.buffers.results.CycleResultSegmentBuffer) CycleResultsSegment(io.engineblock.activityapi.cyclelog.buffers.results.CycleResultsSegment) CycleSegment(io.engineblock.activityapi.cyclelog.buffers.cycles.CycleSegment)

Example 2 with CycleResultSegmentBuffer

use of io.engineblock.activityapi.cyclelog.buffers.results.CycleResultSegmentBuffer in project engineblock by engineblock.

the class CycleResultsArraySegmentReadableTest method testCycleResultSegmentReader.

@Test
public void testCycleResultSegmentReader() {
    CycleResultSegmentBuffer bb = new CycleResultSegmentBuffer(5);
    bb.append(33L, 0);
    bb.append(34L, 1);
    bb.append(35L, 2);
    bb.append(36L, 1);
    bb.append(39L, 0);
    CycleResultsSegment cycleResults = bb.toReader();
    long[] cycles = StreamSupport.stream(cycleResults.spliterator(), false).mapToLong(CycleResult::getCycle).toArray();
    int[] results = StreamSupport.stream(cycleResults.spliterator(), false).mapToInt(CycleResult::getResult).toArray();
    assertThat(cycles).containsExactly(33L, 34L, 35L, 36L, 39L);
    assertThat(results).containsExactly(0, 1, 2, 1, 0);
}
Also used : CycleResultSegmentBuffer(io.engineblock.activityapi.cyclelog.buffers.results.CycleResultSegmentBuffer) CycleResultsSegment(io.engineblock.activityapi.cyclelog.buffers.results.CycleResultsSegment) Test(org.testng.annotations.Test)

Aggregations

CycleResultSegmentBuffer (io.engineblock.activityapi.cyclelog.buffers.results.CycleResultSegmentBuffer)2 CycleResultsSegment (io.engineblock.activityapi.cyclelog.buffers.results.CycleResultsSegment)2 Timer (com.codahale.metrics.Timer)1 CycleSegment (io.engineblock.activityapi.cyclelog.buffers.cycles.CycleSegment)1 Test (org.testng.annotations.Test)1