Package lupos.distributed.operator

Source Code of lupos.distributed.operator.AsynchronSubgraphContainer

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.distributed.operator;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import lupos.datastructures.queryresult.QueryResult;
import lupos.distributed.operator.format.SubgraphContainerFormatter;
import lupos.engine.operators.OperatorIDTuple;
import lupos.engine.operators.index.Dataset;
import lupos.engine.operators.index.Root;
import lupos.engine.operators.messages.EndOfEvaluationMessage;
import lupos.engine.operators.messages.Message;

import org.json.JSONException;
import org.json.JSONObject;

/**
* This class is an adaption of the original {@link SubgraphContainer} that
* processes asynchrony, so that it return immediately {@code null}, but
* processes the result to its succeeding operators if the result is back in
* {@link #preProcessMessage(EndOfEvaluationMessage)}.
*
* @author Bjoern
*
*/
public class AsynchronSubgraphContainer<K> extends SubgraphContainer<K> {

  @Override
  public String toString() {
    return (super.toString().replace("SubgraphContainer",
        "AsynchronSubgraphContainer"));
  }

  /**
   * New asychron working subgraph container
   *
   * @param rootNodeOfSubGraph
   *            the inner root of the subgraph
   * @param key
   *            the key for distribution
   * @param subgraphExecutor
   *            the subgraph executer, for executing inner packed subgraph
   *            container.
   * @throws JSONException
   *             Error during JSON processing
   */
  public AsynchronSubgraphContainer(Root rootNodeOfSubGraph, K key,
      ISubgraphExecutor<K> subgraphExecutor) throws JSONException {
    super(rootNodeOfSubGraph, key, subgraphExecutor);
  }

  /**
   * Creates an {@link AsynchronSubgraphContainer} by an already existing
   * {@link SubgraphContainer}, but without connection to preceding and
   * succeeding operators of the {@link SubgraphContainer}
   *
   * @param c
   *            the {@link SubgraphContainer} to clone to an
   *            {@link AsynchronSubgraphContainer}.
   * @return the new {@link SubgraphContainer} with asynchrony processing
   */
  public static AsynchronSubgraphContainer<?> cloneFrom(SubgraphContainer<?> c) {
    try {
      /*
       * create a new instance with the same root, key and executer and
       * copy all necessary parameter
       */
      AsynchronSubgraphContainer as = new AsynchronSubgraphContainer(
          c.getRootOfSubgraph(), c.getKey(), c.subgraphExecutor);
      as.setCycleOperands(c.getCycleOperands());
      as.setIntersectionVariables(c.getIntersectionVariables());
      as.setUnionVariables(c.getUnionVariables());
      return as;
    } catch (JSONException e) {
      throw new RuntimeException(
          "Error creating asynchron subgraph container");
    }
  }

  /*
   * Object which waits for QueryResult of processing
   */
  private Future<QueryResult> waitForResult;
  private ExecutorService executor;

  @Override
  public QueryResult process(final Dataset dataset) {
    /*
     * Do processing here in a separate thread, and return null, so that the
     * next operation can be processed parallel.
     */
    Callable<QueryResult> c = new Callable<QueryResult>() {
      @Override
      public QueryResult call() throws Exception {
        //Get the processing result asynchron
        final SubgraphContainerFormatter serializer = new SubgraphContainerFormatter();
        try {
          final JSONObject serializedGraph = serializer
              .serialize(AsynchronSubgraphContainer.this
                  .getRootOfSubgraph(), 0);
          final QueryResult result = AsynchronSubgraphContainer.this.subgraphExecutor
              .evaluate(AsynchronSubgraphContainer.this.getKey(),
                  serializedGraph.toString(),bindingsFactory);
          result.materialize();
          result.materialize(); // just for now read all from the
                      // stream sent by the endpoint,
                      // otherwise it may be blocked! (may
                      // be removed if each endpoint can
                      // work completely in parallel!)
         
          return result;
        } catch (final JSONException e) {
          System.err.println(e);
          e.printStackTrace();
          return null;
        }
      }
    };
    /*
     * start processing in a new thread
     */
    executor = Executors.newSingleThreadExecutor();
    waitForResult = executor.submit(c);
    return null;
  }

  @Override
  public Message preProcessMessage(EndOfEvaluationMessage msg) {
    /*
     * if the message arrives before or immediatly after the
     * process()-method, the variable is maybe not set, so wait until the
     * Future is set!
     */
    while (waitForResult == null) {
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
      }
    }
    /*
     * now we want to wait for the result of the subgraph
     */
    QueryResult result;
    try {
      result = waitForResult.get();
    } catch (InterruptedException e) {
      result = null;
      e.printStackTrace();
    } catch (ExecutionException e) {
      result = null;
      e.printStackTrace();
    }
    // for now, forward the result to all succeeding's ....
    if (result != null) result.materialize();
    for (final OperatorIDTuple opId : this.succeedingOperators) {
      if (result != null)
        opId.processAll(result);
    }
    if (executor != null) executor.shutdown();
    return super.preProcessMessage(msg);
  }
}
TOP

Related Classes of lupos.distributed.operator.AsynchronSubgraphContainer

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.