/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.fuseki.async;
import static java.lang.String.format ;
import java.util.* ;
import java.util.concurrent.* ;
import org.apache.jena.fuseki.Fuseki ;
import org.apache.jena.fuseki.server.DataService ;
/** The set of currently active async tasks */
public class AsyncPool
{
private static int nMaxThreads = 4 ;
private static int MAX_FINISHED = 20 ;
// See Executors.newCachedThreadPool and Executors.newFixedThreadPool
private ExecutorService executor = new ThreadPoolExecutor(0, nMaxThreads,
120L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()) ;
private final Object mutex = new Object() ;
private long counter = 0 ;
private Map<String, AsyncTask> runningTasks = new LinkedHashMap<>() ;
private Map<String, AsyncTask> finishedTasks = new LinkedHashMap<>() ;
private static AsyncPool instance = new AsyncPool() ;
public static AsyncPool get()
{ return instance ; }
private AsyncPool() { }
public AsyncTask submit(Runnable task, String displayName, DataService dataService, long requestId) {
synchronized(mutex) {
String taskId = Long.toString(++counter) ;
Fuseki.serverLog.info(format("Task : %s : %s",taskId, displayName)) ;
Callable<Object> c = Executors.callable(task) ;
AsyncTask asyncTask = new AsyncTask(c, this, taskId, displayName, dataService, requestId) ;
Future<Object> x = executor.submit(asyncTask) ;
runningTasks.put(taskId, asyncTask) ;
return asyncTask ;
}
}
public Collection<AsyncTask> tasks() {
synchronized(mutex) {
List<AsyncTask> x = new ArrayList<>(runningTasks.size()+finishedTasks.size()) ;
x.addAll(runningTasks.values()) ;
x.addAll(finishedTasks.values()) ;
return x ;
}
}
public void finished(AsyncTask task) {
synchronized(mutex) {
String id = task.getTaskId() ;
runningTasks.remove(id) ;
while ( finishedTasks.size() >= MAX_FINISHED )
finishedTasks.remove(task.getTaskId()) ;
finishedTasks.put(id, task) ;
}
}
public AsyncTask getRunningTask(String taskId) {
synchronized(mutex) {
return runningTasks.get(taskId) ;
}
}
/** Get for any state */
public AsyncTask getTask(String taskId) {
synchronized(mutex) {
AsyncTask task = runningTasks.get(taskId) ;
if ( task != null )
return task ;
return finishedTasks.get(taskId) ;
}
}
}