Package org.hibernate.search.query

Source Code of org.hibernate.search.query.TimeoutManager

package org.hibernate.search.query;

import java.sql.SQLException;
import java.util.concurrent.TimeUnit;

import org.apache.lucene.search.Query;

import org.hibernate.QueryTimeoutException;
import org.hibernate.search.SearchException;

/**
* @author Emmanuel Bernard
*/
public class TimeoutManager {
  // timeout in nanoseconds
  private Long timeout;
  private long start;
  boolean timedOut = false;
  private Query luceneQuery;
  private Type type;
  private boolean partialResults;


  public TimeoutManager() {
  }

  /** we start counting from this method call (if needed) */
  public void start(Query luceneQuery) {
    if ( timeout == null ) return;
    this.luceneQuery = luceneQuery;
    this.start = System.nanoTime();
    this.partialResults = false;
  }

  public Long getTimeoutLeftInMilliseconds() {
    return getTimeoutLeft( 1000000 );
  }

  public Long getTimeoutLeftInSeconds() {
    return getTimeoutLeft(1000000000);
  }

  private Long getTimeoutLeft(long factor) {
    if (timeout == null) {
      return null;
    }
    else {
      final long currentTime = System.nanoTime();
      if ( isTimedOut( currentTime ) ) {
        //0 means no limit so we return the lowest possible value
        return 0l;
      }
      long left = timeout - ( currentTime - start);
      long result;
      if ( left % factor == 0 ) {
        result = left / factor;
      }
      else {
        result = (left / factor) + 1;
      }
      if ( result <= 0 ) {
        //0 means no limit so we return the lowest possible value
        return 0l;
      }
      else {
        return result;
      }
    }
  }

  public boolean isTimedOut() {
    if ( timeout == null ) return false;
    if ( timedOut ) {
      return true;
    }
    return isTimedOut( System.nanoTime() );
  }

  private boolean isTimedOut(long currentTime) {
    if ( timeout == null ) return false;
    if ( timedOut ) {
      return true;
    }
    else {
      final long elapsedTime = currentTime - start;
      timedOut = elapsedTime > timeout;
      if ( this.type != Type.LIMIT  ) {
        throw new QueryTimeoutException(
            "Full-text query took longer than expected (in microsecond): " + TimeUnit.NANOSECONDS.toMicros( elapsedTime ),
            ( SQLException) null,
            luceneQuery.toString()
        );
      }
      return timedOut;
    }
  }

  public void stop() {
    this.timeout = null;
    this.type = Type.NONE;
    //don't reset, we need it for the query API even when the manager is stopped.
    //this.partialResults = false;
  }

  public void setTimeout(long timeout, TimeUnit timeUnit) {
    this.timeout = timeUnit.toNanos( timeout );
    //timeout of 0 means no more timeout
    if ( timeout == 0 ) {
      stop();
    }
  }

  public void forceTimedOut() {
    this.timedOut = Boolean.TRUE;
    if ( type == Type.LIMIT) {
      //we stop where we are return what we have
      this.partialResults = true;
    }
  }

  public void raiseExceptionOnTimeout() {
    if ( this.type == Type.LIMIT ) {
      throw new SearchException("Cannot define both setTimeout and limitFetchingTime on a full-text query. Please report your need to the Hibernate team");
    }
    this.type = Type.EXCEPTION;
  }

  public void limitFetchingOnTimeout() {
    if ( this.type == Type.EXCEPTION ) {
      throw new SearchException("Cannot define both setTimeout and limitFetchingTime on a full-text query. Please report your need to the Hibernate team");
    }
    this.type = Type.LIMIT;
  }

  public void reactOnQueryTimeoutExceptionWhileExtracting(QueryTimeoutException e) {
    if ( type == Type.LIMIT) {
      //we stop where we are return what we have
      this.partialResults = true;
    }
    else {
      if ( e == null) {
        e = new QueryTimeoutException( "Timeout period exceeded", (SQLException) null, luceneQuery.toString() );
      }
      throw e;
    }
  }

  public boolean hasPartialResults() {
    return partialResults;
  }

  public Type getType() {
    return type;
  }

  public static enum Type {
    NONE,
    EXCEPTION,
    LIMIT
  }
}
TOP

Related Classes of org.hibernate.search.query.TimeoutManager

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.