/* * Copyright 2013 Eediom Inc. * * Licensed 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.araqne.logdb.query.engine; import java.util.concurrent.atomic.AtomicLong; import org.araqne.logdb.QueryCancelException; import org.araqne.logdb.QueryResultClosedException; import org.araqne.logdb.QueryTask; import org.araqne.logdb.QueryTask.TaskStatus; import org.araqne.logdb.QueryTaskEvent; import org.araqne.logdb.QueryTaskListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class QueryTaskRunner extends Thread { private static AtomicLong idCounter = new AtomicLong(1); private final Logger logger = LoggerFactory.getLogger(QueryTaskRunner.class); private QueryTaskScheduler scheduler; private QueryTask task; private int queryId; public QueryTaskRunner(QueryTaskScheduler scheduler, QueryTask task) { this.scheduler = scheduler; this.task = task; this.queryId = scheduler.getQuery().getId(); setName("Query Task #" + idCounter.incrementAndGet() + " for query " + queryId); } @Override public void run() { try { logger.debug("araqne logdb: query [{}] running task [{}]", queryId, task); QueryTaskEvent startEvent = new QueryTaskEvent(task); triggerStartEvent(task, startEvent); task.onStart(); task.setStatus(TaskStatus.RUNNING); task.run(); task.setStatus(TaskStatus.COMPLETED); triggerCompleteEvent(task, new QueryTaskEvent(task)); } catch (QueryResultClosedException e) { logger.debug("araqne logdb: query [" + queryId + "] task [" + task + "] result is already closed"); } catch (QueryCancelException e) { logger.error("araqne logdb: query [" + queryId + "] task [" + task + "] canceled"); task.setStatus(TaskStatus.CANCELED); task.setFailure(e); } catch (Throwable t) { logger.error("araqne logdb: query [" + queryId + "] task [" + task + "] failed", t); task.setStatus(TaskStatus.CANCELED); task.setFailure(t); scheduler.getQuery().cancel(t); } finally { try { task.done(); triggerCleanUpEvent(task, new QueryTaskEvent(task)); task.onCleanUp(); } catch (Throwable t) { logger.error("araqne logdb: query [" + queryId + "] task [" + task + "] cleanup failure", t); } } } private void triggerStartEvent(QueryTask task, QueryTaskEvent event) { for (QueryTaskListener listener : task.getListeners()) { try { listener.onStart(event); } catch (Throwable t) { logger.warn("araqne logdb: query task listener should not throw any exception", t); } } // bubble if (task.getParentTask() != null) if (!event.isHandled()) triggerStartEvent(task.getParentTask(), event); } private void triggerCompleteEvent(QueryTask task, QueryTaskEvent event) { for (QueryTaskListener listener : task.getListeners()) { try { listener.onComplete(event); } catch (Throwable t) { logger.warn("araqne logdb: query task listener should not throw any exception", t); } } // bubble if (task.getParentTask() != null) if (!event.isHandled()) triggerCompleteEvent(task.getParentTask(), event); } private void triggerCleanUpEvent(QueryTask task, QueryTaskEvent event) { for (QueryTaskListener listener : task.getListeners()) { try { listener.onCleanUp(event); } catch (Throwable t) { logger.warn("araqne logdb: query task listener should not throw any exception", t); } } // bubble if (task.getParentTask() != null) if (!event.isHandled()) triggerCleanUpEvent(task.getParentTask(), event); } }