All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.internal.util.executor.LoggingScheduledExecutor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.internal.util.executor;

import com.hazelcast.logging.ILogger;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;

import static com.hazelcast.internal.util.Preconditions.checkNotNull;
import static java.lang.Thread.currentThread;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;

/**
 * Logs execution exceptions by overriding {@link ScheduledThreadPoolExecutor#afterExecute}
 * and {@link ScheduledThreadPoolExecutor#decorateTask} methods.
 * 

* Reasoning is given tasks to {@link ScheduledThreadPoolExecutor} stops silently if there is an * execution exception. *

* Note: Task decoration is only needed to call given tasks {@code toString} methods. *

* {@link java.util.concurrent.ScheduledExecutorService#scheduleWithFixedDelay} *

* Remove on cancel: * To prevent running into an accumulation of cancelled task which can cause gc related problems * (e.g. transactions in combination with LockResource eviction), it is best that tasks are * removed from the scheduler on cancellation. *

* In Java 7+ the there is a method {@code ScheduledThreadPoolExecutor#setRemoveOnCancelPolicy(boolean)} * which removes the runnable on cancellation. Removal of tasks is done in logarithmic time * (see ScheduledThreadPoolExecutor.DelayedWorkQueue.indexOf where there is a direct lookup * instead of a linear scan over the queue). */ public class LoggingScheduledExecutor extends ScheduledThreadPoolExecutor { private final ILogger logger; private volatile boolean shutdownInitiated; public LoggingScheduledExecutor(ILogger logger, int corePoolSize, ThreadFactory threadFactory) { super(corePoolSize, threadFactory); this.logger = checkNotNull(logger, "logger cannot be null"); setRemoveOnCancelPolicy(true); } public LoggingScheduledExecutor(ILogger logger, int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, threadFactory, handler); this.logger = checkNotNull(logger, "logger cannot be null"); setRemoveOnCancelPolicy(true); } @Override protected void afterExecute(Runnable runnable, Throwable throwable) { super.afterExecute(runnable, throwable); Level level = FINE; if (throwable == null && runnable instanceof ScheduledFuture future && future.isDone()) { try { future.get(); } catch (CancellationException ce) { throwable = ce; } catch (ExecutionException ee) { level = SEVERE; throwable = ee.getCause(); } catch (InterruptedException ie) { throwable = ie; currentThread().interrupt(); } } if (throwable instanceof RejectedExecutionException && shutdownInitiated) { level = Level.FINE; } if (throwable != null) { logger.log(level, "Failed to execute " + runnable, throwable); } } public void notifyShutdownInitiated() { shutdownInitiated = true; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy