Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lightweight long-running method cancel pattern for Java

Is there a lightweight pattern to cancel long running method, which replaces code like this:

public void longComputations() {
   ... first step...
   if ( cancelled ) {
      rollbackWork();
      return;
   }
   ... second step...
   if ( cancelled ) {
      rollbackWork();
      return;
   }
   ... third step...
   if ( cancelled ) {
      rollbackWork();
      return;
  }
}

I know that I can make a Task class, subdivide steps to task objects, make a queue and just do tasks step by steps in loop with cancelation checking, but I'm just wondering is there any simple code-structure pattern for such situation.

like image 628
Piotr Müller Avatar asked Sep 28 '13 08:09

Piotr Müller


People also ask

What is the use of cancel() method in Java?

The cancel() method of Timer class is used to terminate this timer and remove any currently scheduled tasks. Syntax: public void cancel() Parameters: The function does not accepts any parameter. Return Value: The method has no return value. Exception: The function does not throws any exception.

Does cancel work when task is running in Java?

However cancel might not always work if the task is running. This is because to stop threads in Java, we rely on a co-operative mechanism called Interruption. The idea is very simple. To stop a thread, we deliver it an interrupt signal, requesting that it stops itself at the next available opportunity.

What is a long-lived task in Java?

The primary thing about a long-lived task is that it should somehow be kept running during the application lifetime. The right way to accomplish this is to provide a thread of execution for a particular task. You create a task as a thread or as an implementation of the java.lang.Runnable interface.

How do I create a long-running class in Java?

If you want to create a long-running class, you need only to extend the Worker class and implement several abstract methods. Let’s look at these methods in more detail. The run () method of the Worker class is designed to continuously execute the work () method until it is stopped.


2 Answers

I am not aware of such a mechanism. Since you have to track your work in order to be able to perform rollbackWork(), a well-designed object-oriented solution is your best choice anyway, if you want to further evolve this logic! Typically, such a scenario could be implemented using the command pattern, which I still find pretty lightweight:

// Task or Command
public interface Command {
    void redo();
    void undo();
}

A scheduler or queue could then take care of executing such task / command implementations, and of rolling them back in order.

like image 186
Lukas Eder Avatar answered Oct 20 '22 00:10

Lukas Eder


How about this edit, not a pattern though? Exceptions are very cheap, so it should be fast.

public void caller(){
    try{
        longComputations();
    } catch (MeaningfulRuntimeException e){
        rollbackWork(e.getStep());
    }
}

public void longComputations() {
   ... first step...
   checkStatus(1);

   ... second step...
   checkStatus(2);

   ... third step...
   checkStatus(3);
}

public void checkStatus(int step){
    if ( cancelled ) {
        ... we may rollback here or throw an exception ...
        throw MeaningfulRuntimeException(step);
    }
}
like image 25
Andrey Chaschev Avatar answered Oct 19 '22 23:10

Andrey Chaschev