I was reading up details of Kafka High level consumer in this link and saw the below statement -
In practice, a more common pattern is to use sleep indefinitely and
use a shutdown hook to trigger clean shutdown.
Are there any examples for doing this or pointers which could help?
This will be an example of an infinite loop
public void run() {
try {
consumer.subscribe(topics);
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Long.MAX_VALUE);
//do something
}
} catch (WakeupException e) {
// do nothing we are shutting down
} finally {
consumer.close();
}
}
public void shutdown() {
consumer.wakeup();
}
}
And this will be your shutdown hook.
#PostConstruct
private void init(){
addShutdownHook();
}
private void addShutdownHook(){
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
shutdown();
}
}));
}
Related
Faced the fact that when the database is unavailable, the queue grows because tasks stop running. What is the best way to set some timeout for tasks executed in method run()? May be there is some good approach with using ExecutorService?
#Service
public class AsyncWriter implements Writer, Runnable {
private LinkedBlockingQueue<Entry> queue = new LinkedBlockingQueue<>();
private volatile boolean terminate = false;
private AtomicInteger completedCounter = new AtomicInteger();
#PostConstruct
private void runAsyncWriter() {
Thread async = new Thread(this);
async.setName("Writer Thread");
async.setPriority(2);
async.start();
}
#Override
public void run() {
while (!terminate) {
try {
Entry entry = queue.take();
dao.save(entry);
completedCounter.incrementAndGet();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void write(Entry entry) {
queue.add(entry);
}
}
Maybe you can try RxJava
https://www.baeldung.com/rx-java
And you can set your aync funtions
Timeout in RxJava
I'm using a few services inheriting from the AbstractScheduledService, which get managed by a ServiceManager. Everything works fine, but now, there's a service whose runOneIteration takes a rather long time, and as the result, my process takes too long to terminate (more than five seconds).
There are other services inheriting from AbstractExecutionThreadService, which had a similar problem, which I could solve via
#Override
protected final void triggerShutdown() {
if (thread != null) thread.interrupt();
}
and storing private volatile thread in the run method. However, there's no triggerShutdown for AbstractScheduledService as stated in this issue.
I already considered alternatives like making runOneIteration do less work, but it's both ugly and inefficient.
I can't override stopAsync as it's final and I can't see anything else. Is there a hook for doing something like this?
Can you work with this? Was there any reason you couldn't add a triggerShutdown yourself?
class GuavaServer {
public static void main(String[] args) throws InterruptedException {
GuavaServer gs = new GuavaServer();
Set<ForceStoppableScheduledService> services = new HashSet<>();
ForceStoppableScheduledService ts = gs.new ForceStoppableScheduledService();
services.add(ts);
ServiceManager manager = new ServiceManager(services);
manager.addListener(new Listener() {
public void stopped() {
System.out.println("Stopped");
}
public void healthy() {
System.out.println("Health");
}
public void failure(Service service) {
System.out.println("Failure");
System.exit(1);
}
}, MoreExecutors.directExecutor());
manager.startAsync(); // start all the services asynchronously
Thread.sleep(3000);
manager.stopAsync();
//maybe make a manager.StopNOW()?
for (ForceStoppableScheduledService service : services) {
service.triggerShutdown();
}
}
public class ForceStoppableScheduledService extends AbstractScheduledService {
Thread thread;
#Override
protected void runOneIteration() throws Exception {
thread = Thread.currentThread();
try {
System.out.println("Working");
Thread.sleep(10000);
} catch (InterruptedException e) {// can your long process throw InterruptedException?
System.out.println("Thread was interrupted, Failed to complete operation");
} finally {
thread = null;
}
System.out.println("Done");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
}
protected void triggerShutdown() {
if (thread != null) thread.interrupt();
}
}
}
I have ExecutorService at class level.
There is a rest point 'url'. So, user will call this API 'n' number of times per day.
How to shutdown the executor service if I define it class level?
CLASS LEVEL: (not sure how to shutdown executor service)
public class A {
private final ExecutorService executorService = Executors.newFixedThreadPool(3);
#GET("/url")
public void executeParallelTask() {
try {
executorService.submit(new Runnable() {
#Override
public void run() {
}
});
}
finally {
executorService.shutdown();
executorService.awaitTermination(12,TIMEUNIT.HOURS)
}
If I shutdown executor service in finally block, when next request comes at rest point, I’m getting Thread Pool size is empty and couldn’t handle the request.
I’m aware of method level like below.
public void executeParallelTask() {
executorService.submit(new Runnable() {
#Override
public void run() {
}
});
executorService.shutdown();
executorService.awaitTermination(12, TimeUnit.HOURS)
You can do it in a shutdown hook.
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
if (executorService.isShutdown()) {
return;
}
log.debug("executorService shutting down...");
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
executorService.shutdownNow();
log.debug("executorService shutdown");
} catch (Throwable e) {
log.error(e, e);
}
}
});
}
Say I have the following test:
#Test(timeout = 1)
public void test(){
while(true){}
}
This simulates a test that would take a long time to return, not from sleeping, but from raw calculation time. How does the test exit? If I create a thread and try the same thing, it does not compile.
public static void main(String[] args) {
Thread thread = new Thread() {
public void run() {
try {
while (true) {
}
} catch (InterruptedException e) {//Exception 'java.lang.InterruptedException' is never thrown in the corresponding try block'
e.printStackTrace();
}
}
};
thread.start();
thread.interrupt();
}
I can even attempt to replicate the implementation, but it still does not interrupt the thread:
public static void main(String[] args) {
Thread thread = new Thread() {
public void run() {
try {
doTest();
} catch (InterruptedException throwable) {
System.out.println("interrupted");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
private void doTest() throws Throwable {
while (true) {
}
}
};
thread.start();
thread.interrupt();
}
The java.lang.Exception: test timed out after 1 milliseconds exception claims to be originating strait from the while loop when running the regular test.
I am confused as to how the test is 'interrupted', but I cannot do the same with a regular thread. How is this 'interrupting' feature implemented in JUnit?
The code tells you the truth: https://github.com/junit-team/junit/blob/master/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
In the Java tutorial it says about try { ... } finally { ... }:
Note: If the JVM exits while the try or catch code is being executed,
then the finally block may not execute. Likewise, if the thread
executing the try or catch code is interrupted or killed, the finally
block may not execute even though the application as a whole
continues.
Is it true that a thread can be interrupted or killed (I thought that was impossible?) such that the finally block will not be executed while the JVM running this thread is not exited/killed? (I am puzzled because the quote above is pretty explicit about this, not much room for misunderstanding.)
Edit: Broke the question down to its core intend.
Well, I stand corrected. It is possible by using deprecated methods:
#Test
public void testThread() throws Exception {
Thread thread = new Thread(new MyRunnable());
thread.start();
Thread.sleep(100);
thread.suspend();
Thread.sleep(2000);
}
class MyRunnable implements Runnable {
#Override
public void run() {
System.out.println("Start");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("Done");
}
}
}
Due to the pausing which will (most likely) occure while the thread is asleep, the finally block will never be executed.
Rafael, I believe this is one of the edge cases you are after. If a thread is blocked on something native (eg reading from STDIN or a Socket), and the JVM is in a state of shutdown, and the thread is interrupted, then finally may not be invoked.
The following example indicates this without invoking deprecated methods:
Sleep - finally is invoked.
SystemIn - finally is not invoked.
The example is very contrived, and is purely provided for demonstrative purposes :)
public class Interrupted {
static final List<Thread> THREADS = Arrays.asList(
new Thread(new Sleep()),
new Thread(new SystemIn())
);
static final CountDownLatch LATCH = new CountDownLatch(THREADS.size());
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook()));
for (Thread thread : THREADS) {
thread.start();
}
System.out.println("[main] Waiting for threads to start...");
LATCH.await();
System.out.println("[main] All started, time to exit");
System.exit(0);
}
static abstract class BlockingTask implements Runnable {
#Override
public void run() {
final String name = getClass().getSimpleName();
try {
LATCH.countDown();
System.out.printf("[%s] is about to block...%n",name);
blockingTask();
} catch (Throwable e) {
System.out.printf("[%s] ", name);
e.printStackTrace(System.out);
} finally {
System.out.printf("[%s] finally%n", name);
}
}
abstract void blockingTask() throws Throwable;
}
static class Sleep extends BlockingTask {
#Override
void blockingTask() throws Throwable {
Thread.sleep(60 * 60 * 1000); // 1 hour
}
}
static class SystemIn extends BlockingTask {
#Override
void blockingTask() throws Throwable {
System.in.read();
}
}
static class ShutdownHook implements Runnable {
#Override
public void run() {
System.out.println("[shutdown-hook] About to interrupt blocking tasks...");
for (Thread thread : THREADS) {
thread.interrupt();
}
System.out.println("[shutdown-hook] Interrupted");
try {
for (int i=0; i<10; i++) {
Thread.sleep(50L);
System.out.println("[shutdown-hook] Still exiting...");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}