001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.hbase.chaos.policies;
020
021import org.apache.hadoop.hbase.DaemonThreadFactory;
022import org.apache.hadoop.hbase.chaos.actions.Action;
023import org.apache.hadoop.hbase.chaos.monkies.PolicyBasedChaosMonkey;
024import org.apache.hadoop.util.StringUtils;
025
026import java.util.concurrent.ExecutionException;
027import java.util.concurrent.ExecutorService;
028import java.util.concurrent.Executors;
029import java.util.concurrent.Future;
030
031/**
032 * Chaos Monkey policy that will run two different actions at the same time.
033 * A random action from each array of actions will be chosen and then run in parallel.
034 */
035public class TwoConcurrentActionPolicy extends PeriodicPolicy {
036  private final Action[] actionsOne;
037  private final Action[] actionsTwo;
038  private final ExecutorService executor;
039
040  public TwoConcurrentActionPolicy(long sleepTime, Action[] actionsOne, Action[] actionsTwo) {
041    super(sleepTime);
042    this.actionsOne = actionsOne;
043    this.actionsTwo = actionsTwo;
044    executor = Executors.newFixedThreadPool(2,
045        new DaemonThreadFactory("TwoConcurrentAction-"));
046  }
047
048  @Override
049  protected void runOneIteration() {
050    Action actionOne = PolicyBasedChaosMonkey.selectRandomItem(actionsOne);
051    Action actionTwo = PolicyBasedChaosMonkey.selectRandomItem(actionsTwo);
052
053    Future fOne = executor.submit(new ActionRunner(actionOne));
054    Future fTwo = executor.submit(new ActionRunner(actionTwo));
055
056    try {
057      fOne.get();
058      fTwo.get();
059    } catch (InterruptedException e) {
060      LOG.warn("Exception occurred during performing action: "
061          + StringUtils.stringifyException(e));
062    } catch (ExecutionException ex) {
063      LOG.warn("Exception occurred during performing action: "
064          + StringUtils.stringifyException(ex));
065    }
066  }
067
068  @Override
069  public void init(PolicyContext context) throws Exception {
070    super.init(context);
071    for (Action a : actionsOne) {
072      a.init(context);
073    }
074    for (Action a : actionsTwo) {
075      a.init(context);
076    }
077  }
078
079  private static class ActionRunner implements Runnable {
080
081    private final Action action;
082
083    public ActionRunner(Action action) {
084
085      this.action = action;
086    }
087
088    @Override public void run() {
089      try {
090        action.perform();
091      } catch (Exception ex) {
092        LOG.warn("Exception occurred during performing action: "
093            + StringUtils.stringifyException(ex));
094      }
095    }
096  }
097}