Search in sources :

Example 1 with FunctionExecutionException

use of org.apache.cassandra.exceptions.FunctionExecutionException in project cassandra by apache.

the class UDFunction method async.

private <T> T async(ThreadIdAndCpuTime threadIdAndCpuTime, Callable<T> callable) {
    Future<T> future = executor().submit(callable);
    try {
        if (DatabaseDescriptor.getUserDefinedFunctionWarnTimeout() > 0)
            try {
                return future.get(DatabaseDescriptor.getUserDefinedFunctionWarnTimeout(), TimeUnit.MILLISECONDS);
            } catch (TimeoutException e) {
                // log and emit a warning that UDF execution took long
                String warn = String.format("User defined function %s ran longer than %dms", this, DatabaseDescriptor.getUserDefinedFunctionWarnTimeout());
                logger.warn(warn);
                ClientWarn.instance.warn(warn);
            }
        // retry with difference of warn-timeout to fail-timeout
        return future.get(DatabaseDescriptor.getUserDefinedFunctionFailTimeout() - DatabaseDescriptor.getUserDefinedFunctionWarnTimeout(), TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new UncheckedInterruptedException(e);
    } catch (ExecutionException e) {
        Throwable c = e.getCause();
        if (c instanceof RuntimeException)
            throw (RuntimeException) c;
        throw new RuntimeException(c);
    } catch (TimeoutException e) {
        // retry a last time with the difference of UDF-fail-timeout to consumed CPU time (just in case execution hit a badly timed GC)
        try {
            // The threadIdAndCpuTime shouldn't take a long time to be set so this should return immediately
            threadIdAndCpuTime.get(1, TimeUnit.SECONDS);
            long cpuTimeMillis = threadMXBean.getThreadCpuTime(threadIdAndCpuTime.threadId) - threadIdAndCpuTime.cpuTime;
            cpuTimeMillis /= 1000000L;
            return future.get(Math.max(DatabaseDescriptor.getUserDefinedFunctionFailTimeout() - cpuTimeMillis, 0L), TimeUnit.MILLISECONDS);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
            throw new UncheckedInterruptedException(e1);
        } catch (ExecutionException e1) {
            Throwable c = e.getCause();
            if (c instanceof RuntimeException)
                throw (RuntimeException) c;
            throw new RuntimeException(c);
        } catch (TimeoutException e1) {
            TimeoutException cause = new TimeoutException(String.format("User defined function %s ran longer than %dms%s", this, DatabaseDescriptor.getUserDefinedFunctionFailTimeout(), DatabaseDescriptor.getUserFunctionTimeoutPolicy() == Config.UserFunctionTimeoutPolicy.ignore ? "" : " - will stop Cassandra VM"));
            FunctionExecutionException fe = FunctionExecutionException.create(this, cause);
            JVMStabilityInspector.userFunctionTimeout(cause);
            throw fe;
        }
    }
}
Also used : FunctionExecutionException(org.apache.cassandra.exceptions.FunctionExecutionException) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException) FunctionExecutionException(org.apache.cassandra.exceptions.FunctionExecutionException) ExecutionException(java.util.concurrent.ExecutionException) UncheckedInterruptedException(org.apache.cassandra.utils.concurrent.UncheckedInterruptedException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

ExecutionException (java.util.concurrent.ExecutionException)1 TimeoutException (java.util.concurrent.TimeoutException)1 FunctionExecutionException (org.apache.cassandra.exceptions.FunctionExecutionException)1 UncheckedInterruptedException (org.apache.cassandra.utils.concurrent.UncheckedInterruptedException)1