use of io.mantisrx.runtime.Context in project mantis by Netflix.
the class LocalJobExecutorNetworked method execute.
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void execute(Job job, SchedulingInfo schedulingInfo, Parameter... parameters) throws IllegalMantisJobException {
// validate job
try {
new ValidateJob(job).execute();
} catch (CommandException e) {
throw new IllegalMantisJobException(e);
}
// execute job
List<StageConfig> stages = job.getStages();
final SourceHolder source = job.getSource();
final SinkHolder sink = job.getSink();
final PortSelector portSelector = new PortSelectorInRange(8000, 9000);
// register netty metrics
RxNetty.useMetricListenersFactory(new MantisNettyEventsListenerFactory());
// start our metrics server
MetricsServer metricsServer = new MetricsServer(portSelector.acquirePort(), 1, Collections.EMPTY_MAP);
metricsServer.start();
Lifecycle lifecycle = job.getLifecycle();
lifecycle.startup();
// create job context
Map parameterDefinitions = job.getParameterDefinitions();
final String user = Optional.ofNullable(System.getenv("USER")).orElse("userUnknown");
String jobId = String.format("localJob-%s-%d", user, (int) (Math.random() * 10000));
logger.info("jobID {}", jobId);
final ServiceLocator serviceLocator = lifecycle.getServiceLocator();
int numInstances = schedulingInfo.forStage(1).getNumberOfInstances();
BehaviorSubject<Integer> workersInStageOneObservable = BehaviorSubject.create(numInstances);
BehaviorSubject<WorkerMap> workerMapObservable = BehaviorSubject.create();
if (stages.size() == 1) {
// single stage job
final StageConfig stage = stages.get(0);
// use latch to wait for all instances to complete
final CountDownLatch waitUntilAllCompleted = new CountDownLatch(numInstances);
Action0 countDownLatchOnComplete = new Action0() {
@Override
public void call() {
waitUntilAllCompleted.countDown();
}
};
Action0 nullOnCompleted = new Action0() {
@Override
public void call() {
}
};
Action1<Throwable> nullOnError = new Action1<Throwable>() {
@Override
public void call(Throwable t) {
}
};
Map<Integer, List<WorkerInfo>> workerInfoMap = new HashMap<>();
List<WorkerInfo> workerInfoList = new ArrayList<>();
// run for num of instances
for (int i = 0; i < numInstances; i++) {
WorkerPorts workerPorts = new WorkerPorts(portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort());
WorkerInfo workerInfo = new WorkerInfo(jobId, jobId, 1, i, i + 1, MantisJobDurationType.Perpetual, "localhost", workerPorts);
workerInfoList.add(workerInfo);
Context context = new Context(ParameterUtils.createContextParameters(parameterDefinitions, parameters), lifecycle.getServiceLocator(), // new WorkerInfo(jobId, jobId, 1, i, i, MantisJobDurationType.Perpetual, "localhost", new ArrayList<>(),-1,-1),
workerInfo, MetricsRegistry.getInstance(), () -> {
System.exit(0);
}, workerMapObservable);
// workers for stage 1
workerInfoMap.put(1, workerInfoList);
workerMapObservable.onNext(new WorkerMap(workerInfoMap));
StageExecutors.executeSingleStageJob(source, stage, sink, () -> workerInfo.getWorkerPorts().getSinkPort(), new RxMetrics(), context, countDownLatchOnComplete, i, workersInStageOneObservable, null, null, nullOnCompleted, nullOnError);
}
// wait for all instances to complete
try {
waitUntilAllCompleted.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
// multi-stage job
int workerNumber = 0;
// start source stages
StageConfig currentStage = stages.get(0);
StageConfig previousStage = null;
StageSchedulingInfo currentStageScalingInfo = schedulingInfo.forStage(1);
StageSchedulingInfo nextStageScalingInfo = schedulingInfo.forStage(2);
// num ports
int[] previousPorts = new int[currentStageScalingInfo.getNumberOfInstances()];
Map<Integer, List<WorkerInfo>> workerInfoMap = new HashMap<>();
List<WorkerInfo> workerInfoList = new ArrayList<>();
for (int i = 0; i < currentStageScalingInfo.getNumberOfInstances(); i++) {
WorkerPorts workerPorts = new WorkerPorts(portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort());
WorkerInfo workerInfo = new WorkerInfo(jobId, jobId, 1, i, i + 1, MantisJobDurationType.Perpetual, "localhost", workerPorts);
workerInfoList.add(workerInfo);
// int sourcePort = portSelector.acquirePort();
int sourcePort = workerInfo.getWorkerPorts().getSinkPort();
previousPorts[i] = sourcePort;
Context context = new Context(ParameterUtils.createContextParameters(parameterDefinitions, parameters), serviceLocator, workerInfo, MetricsRegistry.getInstance(), nullAction, workerMapObservable);
startSource(i, sourcePort, nextStageScalingInfo.getNumberOfInstances(), job.getSource(), currentStage, context, workersInStageOneObservable);
}
// workers for stage 1
workerInfoMap.put(1, workerInfoList);
workerMapObservable.onNext(new WorkerMap(workerInfoMap));
// start intermediate stages, all but last stage
for (int i = 1; i < stages.size() - 1; i++) {
previousStage = currentStage;
StageSchedulingInfo previousStageScalingInfo = schedulingInfo.forStage(i);
// stages indexed starting at 1
currentStageScalingInfo = schedulingInfo.forStage(i + 1);
currentStage = stages.get(i);
// stages indexed starting at 1
nextStageScalingInfo = schedulingInfo.forStage(i + 2);
int[] currentPorts = new int[currentStageScalingInfo.getNumberOfInstances()];
workerInfoList = new ArrayList<>();
for (int j = 0; j < currentStageScalingInfo.getNumberOfInstances(); j++) {
WorkerPorts workerPorts = new WorkerPorts(portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort());
WorkerInfo workerInfo = new WorkerInfo(jobId, jobId, i + 1, j, workerNumber++, MantisJobDurationType.Perpetual, "localhost", workerPorts);
workerInfoList.add(workerInfo);
// int port = portSelector.acquirePort();
int port = workerInfo.getWorkerPorts().getSinkPort();
currentPorts[j] = port;
Context context = new Context(ParameterUtils.createContextParameters(parameterDefinitions, parameters), serviceLocator, workerInfo, MetricsRegistry.getInstance(), nullAction, workerMapObservable);
startIntermediate(previousPorts, port, currentStage, context, j, nextStageScalingInfo.getNumberOfInstances(), i, previousStageScalingInfo.getNumberOfInstances());
}
// workers for current stage
workerInfoMap.put(i + 1, workerInfoList);
workerMapObservable.onNext(new WorkerMap(workerInfoMap));
previousPorts = currentPorts;
}
// start sink stage
StageSchedulingInfo previousStageScalingInfo = schedulingInfo.forStage(stages.size() - 1);
previousStage = stages.get(stages.size() - 2);
currentStage = stages.get(stages.size() - 1);
currentStageScalingInfo = schedulingInfo.forStage(stages.size());
numInstances = currentStageScalingInfo.getNumberOfInstances();
// use latch to wait for all instances to complete
final CountDownLatch waitUntilAllCompleted = new CountDownLatch(numInstances);
Action0 countDownLatchOnTerminated = new Action0() {
@Override
public void call() {
waitUntilAllCompleted.countDown();
}
};
Action0 nullOnCompleted = new Action0() {
@Override
public void call() {
}
};
Action1<Throwable> nullOnError = new Action1<Throwable>() {
@Override
public void call(Throwable t) {
}
};
workerInfoList = new ArrayList<>();
for (int i = 0; i < numInstances; i++) {
WorkerPorts workerPorts = new WorkerPorts(portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort(), portSelector.acquirePort());
WorkerInfo workerInfo = new WorkerInfo(jobId, jobId, stages.size(), i, workerNumber++, MantisJobDurationType.Perpetual, "localhost", workerPorts);
workerInfoList.add(workerInfo);
Context context = new Context(ParameterUtils.createContextParameters(parameterDefinitions, parameters), serviceLocator, workerInfo, MetricsRegistry.getInstance(), nullAction, workerMapObservable);
startSink(previousStage, previousPorts, currentStage, () -> workerInfo.getWorkerPorts().getSinkPort(), sink, context, countDownLatchOnTerminated, nullOnCompleted, nullOnError, stages.size(), i, previousStageScalingInfo.getNumberOfInstances());
}
workerInfoMap.put(stages.size(), workerInfoList);
workerMapObservable.onNext(new WorkerMap(workerInfoMap));
// wait for all instances to complete
try {
waitUntilAllCompleted.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
lifecycle.shutdown();
metricsServer.shutdown();
}
use of io.mantisrx.runtime.Context in project mantis by Netflix.
the class StageExecutors method executeMantisGroups.
@SuppressWarnings("unchecked")
private static <K, T, R> Observable<Observable<R>> executeMantisGroups(Observable<Observable<MantisGroup<K, T>>> go, final Computation computation, final Context context, final long groupTakeUntil) {
logger.info("initializing {}", computation.getClass().getCanonicalName());
computation.init(context);
// from groups to observable
final Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>> c = (Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>>) computation;
return go.lift(new MonitorOperator<>("worker_stage_outer")).map((Func1<Observable<MantisGroup<K, T>>, Observable<R>>) group -> c.call(context, group.lift(new MonitorOperator<>("worker_stage_inner_input"))).lift(new MonitorOperator("worker_stage_inner_output")));
}
use of io.mantisrx.runtime.Context in project mantis by Netflix.
the class StageExecutors method executeMantisGroupsInParallel.
/**
* @param go
* @param computation
*
* @return untyped to support multiple callers return types
*/
@SuppressWarnings("unchecked")
private static <K, T, R> Observable<Observable<R>> executeMantisGroupsInParallel(Observable<Observable<MantisGroup<K, T>>> go, Computation computation, final Context context, final boolean applyTimeoutToInners, final long timeout, final int concurrency) {
logger.info("initializing {}", computation.getClass().getCanonicalName());
computation.init(context);
// from groups to observable
final Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>> c = (Func2<Context, Observable<MantisGroup<K, T>>, Observable<R>>) computation;
if (concurrency == StageConfig.DEFAULT_STAGE_CONCURRENCY) {
return go.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> c.call(context, observable.observeOn(Schedulers.computation()).lift(new MonitorOperator<>("worker_stage_inner_input"))).lift(new MonitorOperator<>("worker_stage_inner_output")));
} else {
final MantisRxSingleThreadScheduler[] mantisRxSingleThreadSchedulers = new MantisRxSingleThreadScheduler[concurrency];
RxThreadFactory rxThreadFactory = new RxThreadFactory("MantisRxSingleThreadScheduler-");
logger.info("creating {} Mantis threads", concurrency);
for (int i = 0; i < concurrency; i++) {
mantisRxSingleThreadSchedulers[i] = new MantisRxSingleThreadScheduler(rxThreadFactory);
}
return go.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> observable.groupBy(e -> Math.abs(e.getKeyValue().hashCode()) % concurrency).flatMap(gbo -> c.call(context, gbo.observeOn(mantisRxSingleThreadSchedulers[gbo.getKey().intValue()]).lift(new MonitorOperator<MantisGroup<K, T>>("worker_stage_inner_input"))).lift(new MonitorOperator<R>("worker_stage_inner_output"))));
}
}
use of io.mantisrx.runtime.Context in project mantis by Netflix.
the class StageExecutors method executeGroupsInParallel.
@SuppressWarnings("unchecked")
private static <K, T, R> Observable<Observable<R>> executeGroupsInParallel(Observable<GroupedObservable<K, T>> go, final Computation computation, final Context context, final long groupTakeUntil) {
logger.info("initializing {}", computation.getClass().getCanonicalName());
computation.init(context);
// from groups to observable
final Func2<Context, GroupedObservable<K, T>, Observable<R>> c = (Func2<Context, GroupedObservable<K, T>, Observable<R>>) computation;
return go.lift(new MonitorOperator<>("worker_stage_outer")).map((Func1<GroupedObservable<K, T>, Observable<R>>) group -> c.call(context, GroupedObservableUtils.createGroupedObservable(group.getKey(), group.doOnUnsubscribe(() -> {
if (groupsExpiredCounter != null)
groupsExpiredCounter.increment();
}).timeout(groupTakeUntil, TimeUnit.SECONDS, (Observable<? extends T>) Observable.empty()).subscribeOn(Schedulers.computation()).lift(new MonitorOperator<T>("worker_stage_inner_input")))).lift(new MonitorOperator("worker_stage_inner_output")));
}
use of io.mantisrx.runtime.Context in project mantis by Netflix.
the class StageExecutors method executeInnersInParallel.
/**
* @param oo
* @param computation
*
* @return untyped to support multiple callers return types
*/
@SuppressWarnings("unchecked")
private static <T, R> Observable<Observable<R>> executeInnersInParallel(Observable<Observable<T>> oo, Computation computation, final Context context, final boolean applyTimeoutToInners, final long timeout, final int concurrency) {
logger.info("initializing {}", computation.getClass().getCanonicalName());
computation.init(context);
// from groups to observable
final Func2<Context, Observable<T>, Observable<R>> c = (Func2<Context, Observable<T>, Observable<R>>) computation;
if (concurrency == StageConfig.DEFAULT_STAGE_CONCURRENCY) {
return oo.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> c.call(context, observable.observeOn(Schedulers.computation()).lift(new MonitorOperator<T>("worker_stage_inner_input"))).lift(new MonitorOperator<R>("worker_stage_inner_output")));
} else {
final MantisRxSingleThreadScheduler[] mantisRxSingleThreadSchedulers = new MantisRxSingleThreadScheduler[concurrency];
RxThreadFactory rxThreadFactory = new RxThreadFactory("MantisRxSingleThreadScheduler-");
logger.info("creating {} Mantis threads", concurrency);
for (int i = 0; i < concurrency; i++) {
mantisRxSingleThreadSchedulers[i] = new MantisRxSingleThreadScheduler(rxThreadFactory);
}
return oo.lift(new MonitorOperator<>("worker_stage_outer")).map(observable -> observable.groupBy(e -> System.nanoTime() % concurrency).flatMap(go -> c.call(context, go.observeOn(mantisRxSingleThreadSchedulers[go.getKey().intValue()]).lift(new MonitorOperator<>("worker_stage_inner_input"))).lift(new MonitorOperator<>("worker_stage_inner_output"))));
}
}
Aggregations