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;
}
}
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);
}
Aggregations