You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/07/09 18:16:55 UTC

git commit: implement SPARQL timeouts (MARMOTTA-267)

Updated Branches:
  refs/heads/develop 17931bd20 -> 51448dc5e


implement SPARQL timeouts (MARMOTTA-267)


Project: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/commit/51448dc5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/tree/51448dc5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-marmotta/diff/51448dc5

Branch: refs/heads/develop
Commit: 51448dc5e7cbb382cbf83640745fa8258473dbeb
Parents: 17931bd
Author: Sebastian Schaffert <ss...@apache.org>
Authored: Tue Jul 9 18:11:38 2013 +0200
Committer: Sebastian Schaffert <ss...@apache.org>
Committed: Tue Jul 9 18:11:38 2013 +0200

----------------------------------------------------------------------
 .../sparql/api/sparql/SparqlService.java        | 69 +++++++++-----
 .../services/sparql/SparqlServiceImpl.java      | 98 ++++++++++++++------
 .../sparql/webservices/SparqlWebService.java    |  4 +-
 3 files changed, 118 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/51448dc5/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/api/sparql/SparqlService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/api/sparql/SparqlService.java b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/api/sparql/SparqlService.java
index 50f10b2..10d40f8 100644
--- a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/api/sparql/SparqlService.java
+++ b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/api/sparql/SparqlService.java
@@ -52,34 +52,59 @@ public interface SparqlService {
 	 */
 	Query parseQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException ;
 
-    /**
-     * Evaluate a SPARQL query on the KiWi TripleStore. Writes the query results 
-     * to the output stream passed as argument on in the output format specified 
-     * as argument outputFormat.
-     *
-     * see http://www.w3.org/TR/sparql11-query/
-     *
-     *
-     * @param queryLanguage the query language to use
-     * @param query         the SPARQL query to evaluate in SPARQL 1.1 syntax
-     * @param tupleWriter   the writer to use to write tuple query results
-     * @param booleanWriter the writer to use to write boolean query results
-     * @param graphWriter
-     * @throws InvalidArgumentException if the output format or query language are undefined
-     * @throws org.apache.marmotta.platform.core.exception.MarmottaException if the query evaluation fails
-     */
-	void query(QueryLanguage queryLanguage, String query, TupleQueryResultWriter tupleWriter, BooleanQueryResultWriter booleanWriter, SPARQLGraphResultWriter graphWriter) throws InvalidArgumentException, MarmottaException, MalformedQueryException, QueryEvaluationException;
+    @Override
+    public void query(QueryLanguage queryLanguage, String query, TupleQueryResultWriter tupleWriter, BooleanQueryResultWriter booleanWriter, SPARQLGraphResultWriter graphWriter, int timeoutInSeconds) throws MarmottaException, MalformedQueryException, QueryEvaluationException {
+        long start = System.currentTimeMillis();
+
+        log.debug("executing SPARQL query:\n{}", query);
+
+
+
+
+        try {
+            RepositoryConnection connection = sesameService.getConnection();
+            try {
+                connection.begin();
+                Query sparqlQuery = connection.prepareQuery(queryLanguage, query);
+
+                if (sparqlQuery instanceof TupleQuery) {
+                    query((TupleQuery) sparqlQuery, tupleWriter);
+                } else if (sparqlQuery instanceof BooleanQuery) {
+                    query((BooleanQuery) sparqlQuery, booleanWriter);
+                } else if (sparqlQuery instanceof GraphQuery) {
+                    query((GraphQuery) sparqlQuery, graphWriter);
+                } else {
+                    connection.rollback();
+                    throw new InvalidArgumentException("SPARQL query type " + sparqlQuery.getClass() + " not supported!");
+                }
+
+                connection.commit();
+            } finally {
+                connection.close();
+            }
+        } catch(RepositoryException e) {
+            log.error("error while getting repository connection: {}", e);
+            throw new MarmottaException("error while getting repository connection", e);
+        } catch (QueryEvaluationException e) {
+            log.error("error while evaluating query: {}", e);
+            throw new MarmottaException("error while writing query result in format ", e);
+        }
+
+        log.debug("SPARQL execution took {}ms", System.currentTimeMillis()-start);
+    }
 
 	/**
 	 * Evaluate a SPARQL query on the KiWi TripleStore. Writes the query results 
      * to the stream passed in the format requested.
      * 
-	 * @param query query
-	 * @param output strem to write 
-	 * @param format mimetype
-	 * @throws MarmottaException
+	 *
+     * @param query query
+     * @param output strem to write
+     * @param format mimetype
+     * @param timeoutInSeconds
+     * @throws MarmottaException
 	 */
-	void query(QueryLanguage language, String query, OutputStream output, String format) throws MarmottaException;
+	void query(QueryLanguage language, String query, OutputStream output, String format, int timeoutInSeconds) throws MarmottaException;
 	
     /**
      * Evaluate a SPARQL ASK query on the KiWi TripleStore

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/51448dc5/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/services/sparql/SparqlServiceImpl.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/services/sparql/SparqlServiceImpl.java b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/services/sparql/SparqlServiceImpl.java
index 99af90d..a7785ad 100644
--- a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/services/sparql/SparqlServiceImpl.java
+++ b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/services/sparql/SparqlServiceImpl.java
@@ -23,7 +23,9 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.*;
 
+import javax.annotation.PostConstruct;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
 
@@ -82,7 +84,21 @@ public class SparqlServiceImpl implements SparqlService {
 
     @Inject
     private SesameService sesameService;
-    
+
+    private ExecutorService executorService;
+
+    private long queryId = 0;
+
+    @PostConstruct
+    public void initialize() {
+        executorService = Executors.newCachedThreadPool(new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(r, "SPARQL Query Thread " + (++queryId));
+            }
+        });
+    }
+
     @Override
     public Query parseQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException {
     	Query sparqlQuery = null;
@@ -98,45 +114,69 @@ public class SparqlServiceImpl implements SparqlService {
     }
 
     @Override
-    public void query(QueryLanguage queryLanguage, String query, TupleQueryResultWriter tupleWriter, BooleanQueryResultWriter booleanWriter, SPARQLGraphResultWriter graphWriter) throws MarmottaException, MalformedQueryException, QueryEvaluationException {
-        long start = System.currentTimeMillis();
+    public void query(final QueryLanguage queryLanguage, final String query, final TupleQueryResultWriter tupleWriter, final BooleanQueryResultWriter booleanWriter, final SPARQLGraphResultWriter graphWriter, int timeoutInSeconds) throws MarmottaException, MalformedQueryException, QueryEvaluationException {
 
         log.debug("executing SPARQL query:\n{}", query);
 
-        try {
-            RepositoryConnection connection = sesameService.getConnection();
-            try {
-                connection.begin();
-                Query sparqlQuery = connection.prepareQuery(queryLanguage, query);
 
-                if (sparqlQuery instanceof TupleQuery) {
-                    query((TupleQuery) sparqlQuery, tupleWriter);
-                } else if (sparqlQuery instanceof BooleanQuery) {
-                    query((BooleanQuery) sparqlQuery, booleanWriter);
-                } else if (sparqlQuery instanceof GraphQuery) {
-                    query((GraphQuery) sparqlQuery, graphWriter);
-                } else {
-                    connection.rollback();
-                    throw new InvalidArgumentException("SPARQL query type " + sparqlQuery.getClass() + " not supported!");
+        Future<Boolean> future = executorService.submit(new Callable<Boolean>() {
+            @Override
+            public Boolean call() throws Exception {
+                long start = System.currentTimeMillis();
+                try {
+                    RepositoryConnection connection = sesameService.getConnection();
+                    try {
+                        connection.begin();
+                        Query sparqlQuery = connection.prepareQuery(queryLanguage, query);
+
+                        if (sparqlQuery instanceof TupleQuery) {
+                            query((TupleQuery) sparqlQuery, tupleWriter);
+                        } else if (sparqlQuery instanceof BooleanQuery) {
+                            query((BooleanQuery) sparqlQuery, booleanWriter);
+                        } else if (sparqlQuery instanceof GraphQuery) {
+                            query((GraphQuery) sparqlQuery, graphWriter);
+                        } else {
+                            connection.rollback();
+                            throw new InvalidArgumentException("SPARQL query type " + sparqlQuery.getClass() + " not supported!");
+                        }
+
+                        connection.commit();
+                    } finally {
+                        connection.close();
+                    }
+                } catch(RepositoryException e) {
+                    log.error("error while getting repository connection: {}", e);
+                    throw new MarmottaException("error while getting repository connection", e);
+                } catch (QueryEvaluationException e) {
+                    log.error("error while evaluating query: {}", e);
+                    throw new MarmottaException("error while writing query result in format ", e);
                 }
 
-                connection.commit();
-            } finally {
-                connection.close();
+                log.debug("SPARQL execution took {}ms", System.currentTimeMillis()-start);
+
+                return Boolean.TRUE;
             }
-        } catch(RepositoryException e) {
-            log.error("error while getting repository connection: {}", e);
-            throw new MarmottaException("error while getting repository connection", e);
-        } catch (QueryEvaluationException e) {
-        	log.error("error while evaluating query: {}", e);
-            throw new MarmottaException("error while writing query result in format ", e);
-        }
+        });
 
-        log.debug("SPARQL execution took {}ms", System.currentTimeMillis()-start);
+        try {
+            Boolean result = future.get(timeoutInSeconds, TimeUnit.SECONDS);
+        } catch (InterruptedException | TimeoutException e) {
+            log.info("SPARQL query execution aborted due to timeout");
+            future.cancel(true);
+        } catch (ExecutionException e) {
+            log.info("SPARQL query execution aborted due to exception");
+            if(e.getCause() instanceof MarmottaException) {
+                throw (MarmottaException)e.getCause();
+            } else if(e.getCause() instanceof MalformedQueryException) {
+                throw (MalformedQueryException)e.getCause();
+            } else {
+                throw new MarmottaException("unknown exception while evaluating SPARQL query",e.getCause());
+            }
+        }
     }
     
     @Override
-    public void query(QueryLanguage language, String query, OutputStream output, String format) throws MarmottaException {
+    public void query(QueryLanguage language, String query, OutputStream output, String format, int timeoutInSeconds) throws MarmottaException {
         long start = System.currentTimeMillis();
 
         log.debug("executing SPARQL query:\n{}", query);

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/51448dc5/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/webservices/SparqlWebService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/webservices/SparqlWebService.java b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/webservices/SparqlWebService.java
index 2383886..b2278cc 100644
--- a/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/webservices/SparqlWebService.java
+++ b/platform/marmotta-sparql/src/main/java/org/apache/marmotta/platform/sparql/webservices/SparqlWebService.java
@@ -455,7 +455,7 @@ public class SparqlWebService {
      * Parse the encoded query parameters
      * 
      * @todo this should be somewhere already implemented
-     * @param string
+     * @param body
      * @return parameters
      */
     private Map<String,String> parseEncodedQueryParameters(String body) {
@@ -484,7 +484,7 @@ public class SparqlWebService {
             @Override
             public void write(OutputStream output) throws IOException, WebApplicationException {
                 try {
-                    sparqlService.query(QueryLanguage.SPARQL,query,getTupleResultWriter(resultType,output),getBooleanResultWriter(resultType,output), getGraphResultWriter(resultType,output));
+                    sparqlService.query(QueryLanguage.SPARQL,query,getTupleResultWriter(resultType,output),getBooleanResultWriter(resultType,output), getGraphResultWriter(resultType,output), configurationService.getIntConfiguration("sparql.timeout", 60));
                 } catch (MarmottaException ex) {
                     throw new WebApplicationException(ex.getCause(), Response.status(Response.Status.BAD_REQUEST).entity(WebServiceUtil.jsonErrorResponse(ex)).build());
                 } catch (QueryEvaluationException e) {