Package bear.core

Source Code of bear.core.GlobalTaskRunner$Stats

package bear.core;

import bear.console.GroupDivider;
import bear.main.event.GlobalStatusEventToUI;
import bear.main.event.NewPhaseConsoleEventToUI;
import bear.main.event.NoticeEventToUI;
import bear.main.event.TaskConsoleEventToUI;
import bear.main.phaser.ComputingGrid;
import bear.main.phaser.Phase;
import bear.main.phaser.PhaseParty;
import bear.main.phaser.SettableFuture;
import bear.session.DynamicVariable;
import bear.session.Variables;
import bear.task.NamedCallable;
import bear.task.Task;
import bear.task.TaskDef;
import bear.task.TaskResult;
import chaschev.lang.LangUtils;
import chaschev.util.Exceptions;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.ListeningExecutorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;

import static bear.core.SessionContext.ui;

/**
* @author Andrey Chaschev chaschev@gmail.com
*/
public class GlobalTaskRunner {
    private static final Logger logger = LoggerFactory.getLogger(GlobalTaskRunner.class);

    private final Bear bear;
    private final BearProject bearSettings;

    List<TaskDef<Object, TaskResult<?>>> taskDefs;
    private final List<SessionContext> $s;

    ComputingGrid<SessionContext, BearScriptPhase<Object, TaskResult<?>>> grid;

    private final long startedAtMs = System.currentTimeMillis();
    private final GlobalContext global;
    private final BearScriptRunner.ShellSessionContext shellContext;

    private final CountDownLatch finishedLatch = new CountDownLatch(1);

    List<ComputingGrid.WhenAllFinished> whenAllFinishedList = new ArrayList<ComputingGrid.WhenAllFinished>();

    public final DynamicVariable<Stats> stats;
    public final DynamicVariable<AtomicInteger> arrivedCount = Variables.newVar(new AtomicInteger(0));

    public GlobalTaskRunner(final GlobalContext global, List<Phase<TaskResult<?>, BearScriptPhase<Object, TaskResult<?>>>> phaseList, final PreparationResult preparationResult) {
        this.global = global;
        this.shellContext = new BearScriptRunner.ShellSessionContext();
        this.bear = global.bear;
        this.$s = preparationResult.getSessions();
        this.bearSettings = preparationResult.bearSettings;

        global.currentGlobalRunner = this;

        for (SessionContext $ : $s) {
            $.setGlobalRunner(this);
        }

        stats = Variables.dynamic(Stats.class)
            .defaultTo(new Stats($s.size(), TaskDef.EMPTY));

        stats.addListener(new DynamicVariable.ChangeListener<Stats>() {
            @Override
            public void changedValue(DynamicVariable<Stats> var, Stats oldValue, Stats newValue) {
                ui.info(new GlobalStatusEventToUI(newValue));
            }
        });

        grid = new ComputingGrid<SessionContext, BearScriptPhase<Object, TaskResult<?>>>(phaseList, $s);

        grid.setPhaseEnterListener(new ComputingGrid.PartyListener<BearScriptPhase<Object, TaskResult<?>>, SessionContext>() {
            @Override
            public void handle(Phase<?, BearScriptPhase<Object, TaskResult<?>>> phase, PhaseParty<SessionContext, BearScriptPhase<Object, TaskResult<?>>> party) {
                ui.info(new NewPhaseConsoleEventToUI("shell", shellContext.sessionId, phase.getPhase().id));
                ui.info(new TaskConsoleEventToUI("shell", "step: " + phase.getName(),
                    phase.getPhase().id)
                     .setId(phase.getPhase().id)
                    .setParentId(shellContext.sessionId)
                );
            }
        });

        grid.setPartyFinishListener(new ComputingGrid.PartyListener<BearScriptPhase<Object, TaskResult<?>>, SessionContext>() {
            @Override
            public void handle(Phase<?, BearScriptPhase<Object, TaskResult<?>>> phase, PhaseParty<SessionContext, BearScriptPhase<Object, TaskResult<?>>> party) {
                String name = phase.getPhase().getName();

                party.getColumn().whenSessionComplete(GlobalTaskRunner.this);

                if(party.failed()){
                    SessionContext.ui.error(new NoticeEventToUI(
                        party.getColumn().getName() +
                            ": Party Failed", "Phase " + name + "(" + Throwables.getRootCause(party.getException()).toString() + ")"));
                }else{
                    SessionContext.ui.fatal(new NoticeEventToUI(
                        party.getColumn().getName(), "Party Finished"));
                }
            }
        });

        grid.setWhenAllFinished(new ComputingGrid.WhenAllFinished() {
            @Override
            public void run(final int failedParties, final int okParties) {
                try {

                    if (failedParties > 0) {
                        SessionContext.ui.error(new NoticeEventToUI("All parties arrived", failedParties + " errors"));
                    } else {
                        SessionContext.ui.fatal(new NoticeEventToUI(null, "All parties arrived"));
                    }

                    for (ComputingGrid.WhenAllFinished callback : whenAllFinishedList) {
                        callback.run(failedParties, okParties);
                    }
                } finally {
                    finishedLatch.countDown();
                }
            }
        });
    }

    static GroupDivider<SessionContext> createGroupDivider() {
        return new GroupDivider<SessionContext>(Stage.SESSION_ID, new Function<SessionContext, String>() {
            public String apply(SessionContext $) {
                DynamicVariable<Task> task = $.getExecutionContext().currentTask;
                return task.isUndefined() || task.getDefaultValue() == null ? null : task.getDefaultValue().getId();
            }
        }, new Function<SessionContext, String>() {
            @Override
            public String apply(SessionContext $) {
                return $.getExecutionContext().phaseText.getDefaultValue().toString();
            }
        });
    }

    public void startParties(ListeningExecutorService localExecutor) {
        grid.startParties(localExecutor);

        arrivedCount.addListener(new DynamicVariable.ChangeListener<AtomicInteger>() {
            @Override
            public void changedValue(DynamicVariable<AtomicInteger> var, AtomicInteger oldValue, AtomicInteger newValue) {
                if (newValue.get() == $s.size()) {
                    logger.debug("finally home. removing interactive run from global scope");

                    global.currentGlobalRunner = null;

                    global.removeConst(bear.internalInteractiveRun);
                }
            }
        });
    }

    public ComputingGrid<SessionContext, BearScriptPhase<Object, TaskResult<?>>> getGrid() {
        return grid;
    }

    public List<SessionContext> getSessions() {
        return $s;
    }

    public void throwIfAnyFailed() {
        if(stats.getDefaultValue().partiesFailed > 0){
            throw new RuntimeException("there are failed parties");
        }
    }

    public static class Stats{
        public final AtomicInteger partiesArrived = new AtomicInteger();
        public final AtomicInteger partiesOk = new AtomicInteger();
        public int partiesPending;
        public int partiesFailed = 0;
        public final AtomicInteger partiesCount;
        protected TaskDef rootTask;
        protected final long startedAt = System.currentTimeMillis();

        public Stats(int count, TaskDef rootTask) {
            partiesPending = count;
            this.rootTask = rootTask;
            partiesCount = new AtomicInteger(count);
        }

        public void addArrival(boolean isOk) {
            partiesArrived.incrementAndGet();
            partiesPending = partiesCount.get() - partiesArrived.get();

            if(isOk){
                partiesOk.incrementAndGet();
            }

            partiesFailed = partiesArrived.get() - partiesOk.get();
        }

        public String getRootTask() {
            return rootTask.getName();
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Stats{");
            sb.append("time: \"").append(LangUtils.millisToSec(System.currentTimeMillis() - startedAt)).append("s\"");
            sb.append(", partiesArrived: ").append(partiesArrived);
            sb.append(", partiesOk: ").append(partiesOk);
            sb.append(", partiesPending: ").append(partiesPending);
            sb.append(", partiesFailed: ").append(partiesFailed);
            sb.append('}');
            return sb.toString();
        }
    }

    public GlobalContext getGlobal() {
        return global;
    }

    public long getStartedAtMs() {
        return startedAtMs;
    }

    public BearProject getBearSettings() {
        return bearSettings;
    }

    public BearScriptRunner.ShellSessionContext getShellContext() {
        return shellContext;
    }

    public CountDownLatch getFinishedLatch() {
        return finishedLatch;
    }

    public GlobalTaskRunner whenAllFinished(ComputingGrid.WhenAllFinished whenAllFinished) {
        this.whenAllFinishedList.add(whenAllFinished);
        return this;
    }

    public SettableFuture<TaskResult<?>> future(String taskDefName, String sessionName){
        return (SettableFuture)grid.future(taskDefName, sessionName, TaskResult.class);
    }

    public <I, O extends TaskResult<?>> SettableFuture<O> future(NamedCallable<I, O> namedCallable, String sessionName) {
        return (SettableFuture<O>) future(namedCallable.getName(), sessionName);
    }

    public <I, O extends TaskResult<?>> SettableFuture<O> future(TaskDef<I, O> taskDef, String sessionName) {
        return (SettableFuture<O>) future(taskDef.getName(), sessionName);
    }

    public TaskResult<?> result(String taskDefName, String sessionName){
        try {
            return future(taskDefName, sessionName).get();
        } catch (InterruptedException e) {
            throw Exceptions.runtime(e);
        } catch (ExecutionException e) {
            throw Exceptions.runtime(e.getCause());
        }
    }

    public <I, O extends TaskResult<?>> O result(NamedCallable<I, O> namedCallable, String sessionName) {
        return (O) result(namedCallable.getName(), sessionName);
    }

    public <I, O extends TaskResult<?>> O result(TaskDef<I, O> taskDef, String sessionName) {
        return (O) result(taskDef.getName(), sessionName);
    }
}
TOP

Related Classes of bear.core.GlobalTaskRunner$Stats

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.